QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#188125 | #7509. 01tree | bulijiojiodibuliduo | TL | 274ms | 26480kb | C++17 | 5.8kb | 2023-09-25 15:21:42 | 2023-09-25 15:21:42 |
Judging History
answer
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef basic_string<int> BI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
mt19937 mrand(1);
const ll mod=1000000007;
int rnd(int x) { return mrand() % x;}
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head
template<int MOD, int RT> struct mint {
static const int mod = MOD;
static constexpr mint rt() { return RT; } // primitive root for FFT
int v; explicit operator int() const { return v; } // explicit -> don't silently convert to int
mint():v(0) {}
mint(ll _v) { v = int((-MOD < _v && _v < MOD) ? _v : _v % MOD);
if (v < 0) v += MOD; }
bool operator==(const mint& o) const {
return v == o.v; }
friend bool operator!=(const mint& a, const mint& b) {
return !(a == b); }
friend bool operator<(const mint& a, const mint& b) {
return a.v < b.v; }
mint& operator+=(const mint& o) {
if ((v += o.v) >= MOD) v -= MOD;
return *this; }
mint& operator-=(const mint& o) {
if ((v -= o.v) < 0) v += MOD;
return *this; }
mint& operator*=(const mint& o) {
v = int((ll)v*o.v%MOD); return *this; }
mint& operator/=(const mint& o) { return (*this) *= inv(o); }
friend mint pow(mint a, ll p) {
mint ans = 1; assert(p >= 0);
for (; p; p /= 2, a *= a) if (p&1) ans *= a;
return ans; }
friend mint inv(const mint& a) { assert(a.v != 0);
return pow(a,MOD-2); }
mint operator-() const { return mint(-v); }
mint& operator++() { return *this += 1; }
mint& operator--() { return *this -= 1; }
friend mint operator+(mint a, const mint& b) { return a += b; }
friend mint operator-(mint a, const mint& b) { return a -= b; }
friend mint operator*(mint a, const mint& b) { return a *= b; }
friend mint operator/(mint a, const mint& b) { return a /= b; }
};
const int MOD=1000000007;
using mi = mint<MOD,5>; // 5 is primitive root for both common mods
namespace simp {
vector<mi> fac,ifac,invn;
void check(int x) {
if (fac.empty()) {
fac={mi(1),mi(1)};
ifac={mi(1),mi(1)};
invn={mi(0),mi(1)};
}
while (SZ(fac)<=x) {
int n=SZ(fac),m=SZ(fac)*2;
fac.resize(m);
ifac.resize(m);
invn.resize(m);
for (int i=n;i<m;i++) {
fac[i]=fac[i-1]*mi(i);
invn[i]=mi(MOD-MOD/i)*invn[MOD%i];
ifac[i]=ifac[i-1]*invn[i];
}
}
}
mi gfac(int x) {
check(x); return fac[x];
}
mi ginv(int x) {
check(x); return invn[x];
}
mi gifac(int x) {
check(x); return ifac[x];
}
mi binom(int n,int m) {
if (m < 0 || m > n) return mi(0);
return gfac(n)*gifac(m)*gifac(n - m);
}
}
const int N=101000;
VI e[N];
int par[N],c0[N],cm[N],d0[N],dm[N],a[N],b[N];
int a0,am,b0,bm,n,m1,m2;
char s1[N],s2[N];
mi ans;
void dfs0(int u,int f) {
for (auto v:e[u]) if (v!=f) {
par[v]=par[u]^1;
dfs0(v,u);
}
}
vector<PII> ps;
const int B=400;
struct ds {
int m1,m2;
int X,Y;
mi pre[N/B+10][N/B+10];
mi prey[N],prex[N],prexy[N*2];
void init(int _m1,int _m2) {
m1=_m1;
m2=_m2;
X=m2;
Y=m1-m2;
if (X>=0&&Y>=0) {
rep(y,0,Y+1) prey[y]=simp::gifac(y)*simp::gifac(Y-y);
rep(x,0,X+1) prex[x]=simp::gifac(x)*simp::gifac(X-x);
rep(xy,0,X+Y) prexy[xy]=simp::gfac(xy)*simp::gfac(X+Y-1-xy);
for (int x0=0;x0<=X;x0+=B) {
mi c0=way(0,0,X,Y);
pre[x0/B][0]=c0;
for (int y0=1;y0<=Y;y0++) {
c0-=way(0,0,x0,y0-1)*way(x0+1,y0-1,X,Y);
if (y0%B==0) pre[x0/B][y0/B]=c0;
}
}
}
}
mi way(int x1,int y1,int x2,int y2) {
return simp::binom(x2+y2-x1-y1,x2-x1);
}
mi query(int p1,int q1) {
if (X<0||Y<0) return 0;
int x0=q1,y0=p1-q1;
if (x0>=X||y0<=0) return way(0,0,X,Y);
if (x0<0||y0>Y) return 0;
mi ans=pre[x0/B][y0/B];
int x1=x0/B*B,y1=y0/B*B;
mi w1=0;
if (x1<X) {
for (int y=y1;y<y0;y++) w1+=prexy[x1+y]*prey[y];
w1*=simp::gifac(x1)*simp::gifac(X-x1-1);
ans-=w1;
}
if (y0>0) {
mi w2=0;
for (int x=x1+1;x<=x0;x++) w2+=prexy[x+y0-1]*prex[x];
ans+=w2*simp::gifac(y0-1)*simp::gifac(Y-y0);
}
return ans;
}
}r1,r2;
void dfs(int u,int f) {
c0[u]=a[u]==0,cm[u]=a[u]==-1;
d0[u]=b[u]==0,dm[u]=b[u]==-1;
for (auto v:e[u]) if (v!=f) {
dfs(v,u);
c0[u]+=c0[v];
cm[u]+=cm[v];
d0[u]+=d0[v];
dm[u]+=dm[v];
}
int p1=cm[u]+dm[u];
int q1=d0[u]+dm[u]-c0[u];
ans+=p1*simp::binom(m1-1,m2-1)-q1*simp::binom(m1,m2);
if (q1>0) {
ans-=2*p1*r1.query(p1-1,q1-1);
ans+=2*q1*r2.query(p1,q1);
}
}
void solve() {
scanf("%d",&n);
rep(i,1,n+1) e[i].clear();
rep(i,1,n) {
int u,v;
scanf("%d%d",&u,&v);
e[u].pb(v);
e[v].pb(u);
}
dfs0(1,0);
scanf("%s",s1+1);
rep(i,1,n+1) {
a[i]=s1[i]=='?'?-1:(s1[i]-'0');
if (a[i]!=-1) a[i]^=par[i];
}
scanf("%s",s2+1);
rep(i,1,n+1) {
b[i]=s2[i]=='?'?-1:(s2[i]-'0');
if (b[i]!=-1) b[i]^=par[i];
}
a0=0,am=0;
b0=0,bm=0;
rep(i,1,n+1) {
a0+=(a[i]==0),am+=(a[i]==-1);
b0+=(b[i]==0),bm+=(b[i]==-1);
}
m1=am+bm;
m2=b0+bm-a0;
r1.init(m1-1,m2-1);
r2.init(m1,m2);
ans=0;
dfs(1,0);
printf("%d\n",(int)ans);
}
mi calc(int p1,int q1) {
mi ans=0;
ans+=p1*simp::binom(m1-1,m2-1)-q1*simp::binom(m1,m2);
rep(det,0,q1+1) ans-=2*p1*simp::binom(p1-1,det-1)*simp::binom(m1-p1,m2-det);
rep(det,0,q1+1) ans+=2*q1*simp::binom(p1,det)*simp::binom(m1-p1,m2-det);
return ans;
}
int _;
int main() {
for (scanf("%d",&_);_;_--) {
solve();
}
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 9804kb
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: 4ms
memory: 9748kb
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: 10180kb
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: 5ms
memory: 9968kb
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: 8ms
memory: 10280kb
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: 161ms
memory: 17292kb
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: 180ms
memory: 17268kb
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: 274ms
memory: 26480kb
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: -100
Time Limit Exceeded
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 ...