QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#187651 | #7509. 01tree | Crysfly | AC ✓ | 106ms | 27660kb | C++14 | 5.3kb | 2023-09-24 19:44:07 | 2023-09-24 19:44:07 |
Judging History
answer
// what is matter? never mind.
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,sse4,popcnt,abm,mmx,avx,avx2")
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
#define ull unsigned long long
#define i128 __int128
//#define int long long
using namespace std;
inline int read()
{
char c=getchar();int x=0;bool f=0;
for(;!isdigit(c);c=getchar())f^=!(c^45);
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
if(f)x=-x;return x;
}
#define mod 1000000007
struct modint{
int x;
modint(int o=0){x=o;}
modint &operator = (int o){return x=o,*this;}
modint &operator +=(modint o){return x=x+o.x>=mod?x+o.x-mod:x+o.x,*this;}
modint &operator -=(modint o){return x=x-o.x<0?x-o.x+mod:x-o.x,*this;}
modint &operator *=(modint o){return x=1ll*x*o.x%mod,*this;}
modint &operator ^=(int b){
modint a=*this,c=1;
for(;b;b>>=1,a*=a)if(b&1)c*=a;
return x=c.x,*this;
}
modint &operator /=(modint o){return *this *=o^=mod-2;}
friend modint operator +(modint a,modint b){return a+=b;}
friend modint operator -(modint a,modint b){return a-=b;}
friend modint operator *(modint a,modint b){return a*=b;}
friend modint operator /(modint a,modint b){return a/=b;}
friend modint operator ^(modint a,int b){return a^=b;}
friend bool operator ==(modint a,int b){return a.x==b;}
friend bool operator !=(modint a,int b){return a.x!=b;}
bool operator ! () {return !x;}
modint operator - () {return x?mod-x:0;}
bool operator <(const modint&b)const{return x<b.x;}
};
inline modint qpow(modint x,int y){return x^y;}
vector<modint> fac,ifac,iv;
inline void initC(int n)
{
if(iv.empty())fac=ifac=iv=vector<modint>(2,1);
int m=iv.size(); ++n;
if(m>=n)return;
iv.resize(n),fac.resize(n),ifac.resize(n);
For(i,m,n-1){
iv[i]=iv[mod%i]*(mod-mod/i);
fac[i]=fac[i-1]*i,ifac[i]=ifac[i-1]*iv[i];
}
}
inline modint C(int n,int m){
if(m<0||n<m)return 0;
return initC(n),fac[n]*ifac[m]*ifac[n-m];
}
inline modint sign(int n){return (n&1)?(mod-1):(1);}
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi;
#define maxn 200005
#define inf 0x3f3f3f3f
int n;
char s[maxn],t[maxn];
vi e[maxn];
int typ(char c){
if(c=='?')return 2;
return c&1;
}
int as[3],at[3],bs[3],bt[3];
struct node{
int A,s1,s2,lim;
modint res;
// j<=lim,\sum C(A,j)*C(s1-A,s2-j)
void adda(){
res-=C(A,lim)*C(s1-A-1,s2-lim-1);
++A;
}
void suba(){
--A;
res+=C(A,lim)*C(s1-A-1,s2-lim-1);
}
void addlim(){
++lim;
res+=C(A,lim)*C(s1-A,s2-lim);
}
void sublim(){
res-=C(A,lim)*C(s1-A,s2-lim);
--lim;
}
void init(){
res=0;
For(j,0,lim)res+=C(A,j)*C(s1-A,s2-j);
}
}T1,T2;
void add(int i){
--bs[s[i]],--bt[t[i]];
++as[s[i]],++at[t[i]];
if(s[i]==2) T1.adda(),T2.adda();
if(t[i]==2) T1.adda(),T2.adda(),T1.addlim(),T2.addlim();
if(s[i]==0) T1.sublim(),T2.sublim();
if(t[i]==0) T1.addlim(),T2.addlim();
}
void sub(int i){
++bs[s[i]],++bt[t[i]];
--as[s[i]],--at[t[i]];
if(s[i]==2) T1.suba(),T2.suba();
if(t[i]==2) T1.suba(),T2.suba(),T1.sublim(),T2.sublim();
if(s[i]==0) T1.addlim(),T2.addlim();
if(t[i]==0) T1.sublim(),T2.sublim();
}
int dep[maxn];
int que[maxn],idx,L[maxn],R[maxn],sz[maxn],son[maxn];
void dfs0(int u,int pa){
que[++idx]=u,L[u]=idx;
sz[u]=1,son[u]=0;
if(dep[u]){
if(s[u]!='?')s[u]^=1;
if(t[u]!='?')t[u]^=1;
}
for(int v:e[u])
if(v!=pa){
dep[v]=dep[u]^1,dfs0(v,u),sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
R[u]=idx;
}
modint res;
void Ins(int u){
For(i,L[u],R[u]) add(que[i]);
}
void Del(int u){
For(i,L[u],R[u]) sub(que[i]);
}
void calc(){
int A=as[2]+at[2],AA=at[2]-as[0]+at[0];
int B=bs[2]+bt[2],BB=bt[2]-bs[0]+bt[0];
// A+B = s? + t?
// AA+BB = t?-s0+t0
modint res1=0,res2=0;
// For(j,0,n){
// res1+=C(A,AA-j)*C(B,BB+j);
// res2+=C(A,AA-j)*C(B-1,BB+j-1);
// }
res1=T1.res;
res2=T2.res;
res2*=B;
res+=2*(res2-res1*BB);
res1=C(A+B,AA+BB);
res2=C(A+B-1,AA+BB-1)*B;
res-=res2-res1*BB;
}
void dfs(int u,int pa){
for(int v:e[u])
if(v!=pa && v!=son[u]){
dfs(v,u);
Del(v);
}
if(son[u]) dfs(son[u],u);
for(int v:e[u])
if(v!=pa && v!=son[u]) Ins(v);
add(u);
if(pa) calc();
}
void work()
{
n=read(); res=0;
For(i,1,n)e[i].clear();idx=0;
For(i,2,n){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
cin>>(s+1)>>(t+1);
dep[1]=0,dfs0(1,0);
For(i,1,n) s[i]=typ(s[i]),t[i]=typ(t[i]);
For(i,0,2) as[i]=at[i]=bs[i]=bt[i]=0;
For(i,1,n) ++bs[s[i]],++bt[t[i]];
T1.s1=bs[2]+bt[2];
T1.s2=bt[2]-bs[0]+bt[0];
T2.s1=T1.s1-1;
T2.s2=T1.s2-1;
T1.lim=T2.lim=0;
T1.A=T2.A=0;
T1.init(),T2.init();
dfs(1,0);
cout<<res.x<<"\n";
}
signed main()
{
int T=read();
while(T--)work();
return 0;
}
/*
C(n,m) * m == C(n-1,m-1) * n
fac[n] * ifac[m-1] * ifac[n-m]
C(n-1,m-1) * n
fac[n-1] * ifac[m-1] * ifac[n-m]
C(m,k)*k
C(m-1,k-1)*m
1 4 7 10 3 6 9 2 5 8 11
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
我发现这题里 A+B 和 AA+BB 是定值,所以应该能移动端点
*/
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 11384kb
input:
3 2 1 2 00 11 3 1 2 2 3 ??? ??? 3 1 2 2 3 ??1 0?0
output:
1 16 1
result:
ok 3 number(s): "1 16 1"
Test #2:
score: 0
Accepted
time: 7ms
memory: 12676kb
input:
1000 23 1 2 1 3 1 4 2 5 5 6 4 7 3 8 4 9 8 10 8 11 8 12 1 13 7 14 10 15 7 16 7 17 5 18 18 19 12 20 9 21 21 22 6 23 00?10?0000??1?00111?010 011??1?10?01?110?0??101 6 1 2 1 3 1 4 4 5 3 6 000?10 1???01 25 1 2 2 3 2 4 4 5 5 6 2 7 4 8 5 9 7 10 8 11 11 12 5 13 11 14 3 15 6 16 14 17 1 18 4 19 6 20 4 21 5 22...
output:
53545 24 11724 2228 162 14 711 28 550 1680 52 2 13 988 9480 2342 626416 0 71780 1 88 39207 19448 4 37395 9602 3253496 38057200 1066 3 303732 1608 281022 11718 170 78 15 1219376 29364 9092 7 0 2 7014 1942448 170371 75845 167217 16554 64 904 564290 14822 1127090 1758504 1227646 14833316 14954550 36055...
result:
ok 1000 numbers
Test #3:
score: 0
Accepted
time: 0ms
memory: 11548kb
input:
1 3000 1 2 2 3 2 4 1 5 3 6 2 7 5 8 8 9 9 10 10 11 2 12 11 13 7 14 11 15 7 16 13 17 8 18 1 19 11 20 10 21 18 22 7 23 7 24 15 25 23 26 24 27 14 28 15 29 25 30 16 31 6 32 10 33 3 34 30 35 16 36 9 37 36 38 28 39 26 40 33 41 1 42 11 43 20 44 23 45 14 46 31 47 41 48 11 49 48 50 45 51 6 52 10 53 32 54 38 5...
output:
924036898
result:
ok 1 number(s): "924036898"
Test #4:
score: 0
Accepted
time: 4ms
memory: 11924kb
input:
1 3000 1 2 1 3 2 4 2 5 3 6 3 7 4 8 4 9 5 10 5 11 6 12 6 13 7 14 7 15 8 16 8 17 9 18 9 19 10 20 10 21 11 22 11 23 12 24 12 25 13 26 13 27 14 28 14 29 15 30 15 31 16 32 16 33 17 34 17 35 18 36 18 37 19 38 19 39 20 40 20 41 21 42 21 43 22 44 22 45 23 46 23 47 24 48 24 49 25 50 25 51 26 52 26 53 27 54 2...
output:
429465738
result:
ok 1 number(s): "429465738"
Test #5:
score: 0
Accepted
time: 0ms
memory: 11848kb
input:
1 3000 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52 5...
output:
650625747
result:
ok 1 number(s): "650625747"
Test #6:
score: 0
Accepted
time: 70ms
memory: 16700kb
input:
1 100000 1 2 1 3 3 4 1 5 2 6 6 7 2 8 1 9 6 10 1 11 3 12 11 13 5 14 9 15 12 16 6 17 13 18 13 19 14 20 7 21 14 22 21 23 12 24 17 25 14 26 3 27 4 28 8 29 22 30 12 31 6 32 30 33 4 34 15 35 12 36 3 37 20 38 7 39 37 40 5 41 13 42 34 43 9 44 27 45 39 46 43 47 3 48 17 49 36 50 12 51 1 52 45 53 35 54 15 55 2...
output:
143309878
result:
ok 1 number(s): "143309878"
Test #7:
score: 0
Accepted
time: 75ms
memory: 16136kb
input:
1 100000 1 2 1 3 2 4 2 5 3 6 3 7 4 8 4 9 5 10 5 11 6 12 6 13 7 14 7 15 8 16 8 17 9 18 9 19 10 20 10 21 11 22 11 23 12 24 12 25 13 26 13 27 14 28 14 29 15 30 15 31 16 32 16 33 17 34 17 35 18 36 18 37 19 38 19 39 20 40 20 41 21 42 21 43 22 44 22 45 23 46 23 47 24 48 24 49 25 50 25 51 26 52 26 53 27 54...
output:
724432513
result:
ok 1 number(s): "724432513"
Test #8:
score: 0
Accepted
time: 19ms
memory: 25564kb
input:
1 100000 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52...
output:
164448583
result:
ok 1 number(s): "164448583"
Test #9:
score: 0
Accepted
time: 73ms
memory: 17908kb
input:
1 100000 1 2 1 3 1 4 4 5 2 6 5 7 3 8 5 9 9 10 6 11 4 12 6 13 11 14 1 15 6 16 15 17 6 18 6 19 8 20 11 21 1 22 11 23 20 24 9 25 2 26 5 27 14 28 7 29 28 30 10 31 7 32 17 33 2 34 24 35 14 36 10 37 2 38 5 39 39 40 14 41 35 42 25 43 33 44 11 45 41 46 1 47 33 48 36 49 25 50 20 51 13 52 4 53 46 54 45 55 21 ...
output:
159386883
result:
ok 1 number(s): "159386883"
Test #10:
score: 0
Accepted
time: 106ms
memory: 17644kb
input:
1 100000 1 2 1 3 2 4 2 5 3 6 3 7 4 8 4 9 5 10 5 11 6 12 6 13 7 14 7 15 8 16 8 17 9 18 9 19 10 20 10 21 11 22 11 23 12 24 12 25 13 26 13 27 14 28 14 29 15 30 15 31 16 32 16 33 17 34 17 35 18 36 18 37 19 38 19 39 20 40 20 41 21 42 21 43 22 44 22 45 23 46 23 47 24 48 24 49 25 50 25 51 26 52 26 53 27 54...
output:
752214506
result:
ok 1 number(s): "752214506"
Test #11:
score: 0
Accepted
time: 23ms
memory: 27660kb
input:
1 100000 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52...
output:
419022702
result:
ok 1 number(s): "419022702"