JNday5-pm
GG
T1
貌似没有读懂题目,然而这是个简单的模拟
T2
首先 & 和 | 都是单调的,
& 和 | 可以用ST表来维护,枚举左端点,计算右端的的数量
利用ST表进行二分,跳过连续段
T3
又是一个GG的dp
背包?f[i][j] 表示i 号节点在子树中拿j 个果子的方案数。
O(n3)?
DFS 时可以直接把父节点状态传下去,减少一维合并复杂度。
O(n2)
T1 轮换
#include <cstdio> #include <algorithm> using namespace std; int n,m,k; int a[1005],b[1005],p[1005][1005]; int main(){ freopen("rotate.in","r",stdin); freopen("rotate.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) a[i]=i; for(int i=1,t;i<=m;i++){ scanf("%d",&t); for(int j=1;j<=t;j++){ scanf("%d",&b[j]); } for(int j=1;j<=n;j++) p[i][j] = j; for(int j=1;j<t;j++) p[i][b[j]] = b[j+1]; p[i][b[t]] = b[1]; } for(int i=1;i<=n;i++){ int x = i; for(int j=m;j>=1;j--){ x=p[j][x]; } printf("%d ",x); } return 0; }
T2 区间
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <algorithm> #include <cassert> using namespace std; typedef long long LL; LL mod = 1e9+7; LL cnt; int s[100005],n,a,b,c,d; int sta[100005][20],sto[100005][20]; int aska(int l,int r){ int L=r-l+1; int t = log2(L); return sta[l][t] & sta[r-(1<<t)+1][t]; } int asko(int l,int r){ int L=r-l+1; int t = log2(L); return sto[l][t] | sto[r-(1<<t)+1][t]; } int main(){ freopen("range.in","r",stdin); freopen("range.out","w",stdout); scanf("%d%d%d%d%d",&n,&a,&b,&c,&d); for(int i=1;i<=n;i++) scanf("%d",&s[i]),sta[i][0]=sto[i][0]=s[i]; // puts("aaa"); for(int j=1;j<20;j++) for(int i=1;i<=n;i++){ if(i+(1<<j) -1 <=n){ sta[i][j] = sta[i][j-1] & sta[i+(1<<(j-1))][j-1]; sto[i][j] = sto[i][j-1] | sto[i+(1<<(j-1))][j-1]; } } for(int i=1;i<=n;i++){ int andsum = s[i], orsum = s[i]; for(int j=i;j<=n;j++){ int L=j,R=n+1; andsum = aska(i,j); orsum = asko(i,j); while(R-L>1){ int mid = (L+R)/2; if(aska(i,mid) == andsum && asko(i,mid) == orsum){ L=mid; }else R=mid; } if(a <= andsum && andsum <= b && c <= orsum && orsum <= d){ cnt += L-j+1; } j=L; } } cout<<cnt%mod<<endl; return 0; }
T3 收集果子
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef long long LL; LL mod = 1e9+7; int n,k; int a[1005]; int H[1005],X[2005],P[2005],tot; inline void add(int x,int y){ P[++tot]=y;X[tot]=H[x];H[x]=tot; } LL pw2[1005]; LL dp[1005][1005]; int dfs(int x,int fa){ int siz=1; for(int i=H[x];i;i=X[i]){ if(fa == P[i]) continue; for(int j=0;j<=n-a[P[i]];j++){ dp[P[i]][j+a[P[i]]] = dp[x][j]; } int tmp = dfs(P[i],x); for(int j=0;j<=n;j++){ dp[x][j] = (pw2[tmp-1] * dp[x][j] % mod + dp[P[i]][j])% mod; } siz+=tmp; } return siz; } int main(){ freopen("fruit.in","r",stdin); freopen("fruit.out","w",stdout); scanf("%d%d",&n,&k); pw2[0]= 1; for(int i=1;i<=n;i++) pw2[i] = pw2[i-1] * 2 % mod; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1,x,y;i<n;i++){ scanf("%d%d",&x,&y); add(x,y);add(y,x); } dp[1][a[1]] = 1; dfs(1,0); printf("%d\n",(int)dp[1][k]); return 0; }