3394: 雪後村莊
時間限制:1 Sec 內存限制: 512 MB題目描述
輸入
輸出
輸出q行,每行一個字符串“yes”或“no”(不包括引號)。
樣例輸入
2 4
3 4
1 2 3
2 3 2
2 4 4
1 2 3
1 3 2
2 3 2
3 4 4
4
1 3 3
1 3 2
1 4 3
3 4 4
樣例輸出
no
yes
no
no
提示
介於個人能力蒟蒻,,哈希代碼一直沒過,但是出人意料的暴力強判居然過了(哈希代碼已交由神犇拯救。。)
補充:在神犇幫助下,發現有個變量打錯了,已經過了,但是還是沒有暴力強判快。。。
Code:
無哈希,強判:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int Maxn = 200005;
const int Maxm = 200005;
const int Max = 300005;
const int MOD = 1000000007;
struct LINE{
int s, t, val, pos;
bool operator < (const LINE & X) const{
if(val == X.val) return pos > X.pos;
return val < X.val;
}
}L[Maxm << 1];
struct node{
int v, nxt;
}edge[Maxm << 1];
int Farm, N, All, cnt, Q;
int m[Maxn], fir[Maxn];
int Color[Maxm];
bool An[Maxm];
vector<int>Id[Maxn + 5];
vector<int>Cnt[Maxn + 5];
bool getint(int & num){
char c; int flg = 1; num = 0;
while((c = getchar()) < '0' || c > '9'){
if(c == '-') flg = -1;
if(c == -1) return 0;
}
while(c >= '0' && c <= '9'){
num = num * 10 + c - 48;
if((c = getchar()) == -1) return 0;
}
num *= flg;
return 1;
}
void addedge(int a, int b){
edge[++ cnt].v = b, edge[cnt].nxt = fir[a], fir[a] = cnt;
}
bool Check(int u, int v){
for(int i = 0; i < Farm; ++ i)
if(Id[u][i] != Id[v][i]) return 0;
return 1;
}
void exchange(int u, int col){
int v = u % N, k = u / N;
if(! v) v = N, -- k;
Id[v][k] = col;
}
void Change(int u, int clr, int ff){
exchange(u, clr);
Color[u] = clr;
for(int i = fir[u]; i; i = edge[i].nxt) if(edge[i].v != ff)
Change(edge[i].v, clr, u);
}
void Together(int l, int r, int pos){
int a = Color[l], b = Color[r];
if(Cnt[pos][a] > Cnt[pos][b])
Change(r, a, 0), Cnt[pos][a] += Cnt[pos][b], Cnt[pos][b] = 0;
else Change(l, b, 0), Cnt[pos][b] += Cnt[pos][a], Cnt[pos][a] = 0;
addedge(l, r), addedge(r, l);
}
int main(){
//freopen("snow.in", "r", stdin);
//freopen("snow.out", "w", stdout);
getint(Farm), getint(N);
All = Farm * N;
for(int i = 1; i <= Farm; ++ i)
getint(m[i]), m[i] += m[i - 1];
Cnt[1].push_back(0);
for(int i = 1; i <= N; ++ i){
Color[i] = i;
Id[i].push_back(Color[i]);
Cnt[1].push_back(1);
}
for(int i = 2; i <= Farm; ++ i){
Cnt[i].push_back(0);
for(int j = 1; j <= N; ++ j){
Color[(i - 1) * N + j] = j;
Cnt[i].push_back(1);
Id[j].push_back(j);
}
}
for(int i = 1; i <= Farm; ++ i)
for(int j = m[i - 1] + 1; j <= m[i]; ++ j)
getint(L[j].s), getint(L[j].t), getint(L[j].val), L[j].pos = i;
getint(Q);
for(int i = 1; i <= Q; ++ i)
getint(L[i + m[Farm]].s), getint(L[i + m[Farm]].t), getint(L[i + m[Farm]].val), L[i + m[Farm]].pos = Farm + i;
sort(L + 1, L + 1 + Q + m[Farm]);
for(int i = Q + m[Farm]; i; -- i){
if(L[i].pos <= Farm){
int l = (L[i].pos - 1) * N + L[i].s;
int r = (L[i].pos - 1) * N + L[i].t;
if(Color[l] != Color[r])
Together(l, r, L[i].pos);
}
else {
if(Check(L[i].s, L[i].t)) An[L[i].pos - Farm] = 1;
else An[L[i].pos - Farm] = 0;
}
}
for(int i = 1; i <= Q; ++ i)
if(! An[i]) puts("no");
else puts("yes");
return 0;
}
Hash:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
const int Maxn = 200005;
const int Maxm = 200005;
const int Max = 300005;
const int MOD = 1000000007;
struct LINE{
int s, t, val, pos;
bool operator < (const LINE & X) const{
if(val == X.val) return pos > X.pos;
return val < X.val;
}
}L[Maxm << 1];
struct node{
int v, nxt;
}edge[Maxm << 1];
int Farm, N, All, cnt, Q;
int m[Maxn], fir[Maxn];
int Color[Maxm];
int Hash[Maxm], qmul[Maxm];
bool An[Maxm];
vector<int>Id[Maxn + 5];
vector<int>Cnt[Maxn + 5];
bool getint(int & num){
char c; int flg = 1; num = 0;
while((c = getchar()) < '0' || c > '9'){
if(c == '-') flg = -1;
if(c == -1) return 0;
}
while(c >= '0' && c <= '9'){
num = num * 10 + c - 48;
if((c = getchar()) == -1) return 0;
}
num *= flg;
return 1;
}
void addedge(int a, int b){
edge[++ cnt].v = b, edge[cnt].nxt = fir[a], fir[a] = cnt;
}
void Pre(){
int k = 7;
qmul[0] = k;
for(int i = 1; i < Farm; ++ i) qmul[i] = 1ll * qmul[i - 1] * k % MOD;//就是這裏,是Farm不是N
}
void exchange(int u, int col){
int v = u % N, k = u / N;
if(! v) v = N, -- k;
Hash[v] = (Hash[v] - 1ll * Id[v][k] * qmul[k] % MOD + MOD) % MOD;
Id[v][k] = col;
Hash[v] = (Hash[v] + 1ll * Id[v][k] * qmul[k] % MOD) % MOD;
}
void Change(int u, int clr, int ff){
exchange(u, clr);
Color[u] = clr;
for(int i = fir[u]; i; i = edge[i].nxt) if(edge[i].v != ff)
Change(edge[i].v, clr, u);
}
void Together(int l, int r, int pos){
int a = Color[l], b = Color[r];
if(Cnt[pos][a] > Cnt[pos][b])
Change(r, a, 0), Cnt[pos][a] += Cnt[pos][b], Cnt[pos][b] = 0;
else Change(l, b, 0), Cnt[pos][b] += Cnt[pos][a], Cnt[pos][a] = 0;
addedge(l, r), addedge(r, l);
}
int main(){
//freopen("snow.in", "r", stdin);
//freopen("snow.out", "w", stdout);
getint(Farm), getint(N);
Pre();
for(int i = 1; i <= Farm; ++ i)
getint(m[i]), m[i] += m[i - 1];
Cnt[1].push_back(0);
for(int i = 1; i <= N; ++ i){
Color[i] = i;
Id[i].push_back(Color[i]);
Hash[i] = 1ll * i * qmul[0] % MOD;
Cnt[1].push_back(1);
}
for(int i = 2; i <= Farm; ++ i){
Cnt[i].push_back(0);
for(int j = 1; j <= N; ++ j){
Color[(i - 1) * N + j] = j;
Cnt[i].push_back(1);
Hash[j] = (Hash[j] + 1ll * j * qmul[i - 1] % MOD) % MOD;
Id[j].push_back(j);
}
}
for(int i = 1; i <= Farm; ++ i)
for(int j = m[i - 1] + 1; j <= m[i]; ++ j)
getint(L[j].s), getint(L[j].t), getint(L[j].val), L[j].pos = i;
getint(Q);
for(int i = 1; i <= Q; ++ i)
getint(L[i + m[Farm]].s), getint(L[i + m[Farm]].t), getint(L[i + m[Farm]].val), L[i + m[Farm]].pos = Farm + i;
sort(L + 1, L + 1 + Q + m[Farm]);
for(int i = Q + m[Farm]; i; -- i){
if(L[i].pos <= Farm){
int l = (L[i].pos - 1) * N + L[i].s;
int r = (L[i].pos - 1) * N + L[i].t;
if(Color[l] != Color[r])
Together(l, r, L[i].pos);
}
else {
if(Hash[L[i].s] == Hash[L[i].t]) An[L[i].pos - Farm] = 1;
else An[L[i].pos - Farm] = 0;
}
}
for(int i = 1; i <= Q; ++ i)
if(! An[i]) puts("no");
else puts("yes");
return 0;
}