T1
找规律或者dp都行
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #include <cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int using namespace std; inline void read(int &x) { x=0; char q=getchar(); while(q<'0'||q>'9') q=getchar(); while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar(); } const int mod=10000; const int N=1006; int T; int n,K; ll f[N][N],g[N]; int main(){ //freopen("T1biao2.out","w",stdout); rint i,j; int q1; f[1][0]=1; g[0]=1; for(i=1;i<=1000;++i) g[i]=1; for(i=2;i<=1000;++i) { for(j=0;j<=1000;++j) { q1=j-i; if(q1<0) f[i][j]=g[j]%mod; else f[i][j]=(g[j]-g[q1]+mod)%mod; } g[0]=f[i][0]; for(j=1;j<=1000;++j) g[j]=(g[j-1]+f[i][j])%mod; } /*for(i=1;i<=10;++i) { for(j=0;j<=50;++j) printf("%lld ",f[i][j]); printf(" "); }*/ read(T); while(T--) { read(n); read(K); printf("%lld ",f[n][K]%mod); } }
T2
原题
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #include <cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int using namespace std; inline void read(int &x) { x=0; int ff=1; char q=getchar(); while(q<'0'||q>'9') { if(q=='-')ff=-1; q=getchar(); } while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar(); x*=ff; } const int N=2006; int n,Q; int a[N],an[N]; int t[4006]; int mx[20006]; void build(int l,int r,int x) { if(l==r) { mx[x]=an[l]; return ; } int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); mx[x]=max(mx[x<<1],mx[x<<1|1]); } int qq(int L,int R,int l,int r,int x) { if(L<=l&&r<=R) return mx[x]; int mid=(l+r)>>1,ans=0; if(L<=mid) ans=max(ans,qq(L,R,l,mid,x<<1)); if(mid<R) ans=max(ans,qq(L,R,mid+1,r,x<<1|1)); return ans; } void chu() { rint i,j; int now; for(i=1;i<=n;++i) { mem(t,-1); now=2000; t[now]=0; for(j=1;j<i;++j) { if(a[j]<=a[i]) --now; else ++now; if(t[now]==-1) t[now]=j; } if(t[now]!=-1&&an[i]<i-t[now]) an[i]=i-t[now]; for(j=i+1;j<=n;++j) { if(a[j]<a[i]) --now; else ++now; if(t[now]!=-1&&an[i]<j-t[now]) an[i]=j-t[now]; } } build(1,n,1); } int main(){ freopen("T2.in","r",stdin); freopen("T2.out","w",stdout); rint i,j; read(n); for(i=1;i<=n;++i) read(a[i]); chu(); read(Q); int l,r; while(Q--) { read(l); read(r); printf("%d ",qq(l,r,1,n,1)); } }
T3
前两道都太水了...
(1)
在0、1trie上行走,当前这一位是1,则下一位0、1都行
如果是0,则只能是0
如果走到这一位,以后都是1,就直接返回
这是剪枝,蒟蒻代码打得常数大,所以没剪枝被卡了70...
其实我考试想到了,但是我觉得没用,然后就懒得打了...
(2)
据 j=x;j;j=(j-1)&x 来不多余的枚举子集,这个暴力跑得飞快
(3)
正解 是一种空间换时间的做法
f[pr][nx] 表示前8位是pr,后8位是nx的个数
那更新的时候确定前8位,更新后8位包含它的
询问就确定后8位,累加前8位它包含的
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #include <cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int #define pr(x) ((x)->pr) #define v(x) ((x)->v) #define nx(x) ((x)->nx) using namespace std; inline void read(int &x) { x=0; char q=getchar(); while(q<'0'||q>'9') q=getchar(); while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar(); } const int N=200006; struct trie { int sum; trie *ch[2]; trie(){sum=0;ch[0]=ch[1]=NULL;} }*root,a1[17*N]; int size,Q; char s[10]; inline trie* newtrie() { return &a1[size++]; } inline void add(int val) { trie *now=root; int tt; ++now->sum; for(int i=15;i>=0;--i) { tt=(val&(1<<i))>>i; if(now->ch[tt]==NULL) now->ch[tt]=newtrie(); now=now->ch[tt]; ++now->sum; } } inline void del(int val) { trie *now=root; int tt; --now->sum; for(int i=15;i>=0;--i) { tt=((val&(1<<i))>>i); if(now->ch[tt]==NULL) now->ch[tt]=newtrie(); now=now->ch[tt]; --now->sum; } } int ans,vv,limit; void dfs(trie *x,int dep) { if(x==NULL) return ; if(!(x->sum)) return ; if(dep==limit) { ans+=x->sum; return; } if( (1<<dep)&vv ) dfs(x->ch[0],dep-1),dfs(x->ch[1],dep-1); else dfs(x->ch[0],dep-1); } int main(){ //freopen("T3.in","r",stdin); //freopen("T3trie.out","w",stdout); root=newtrie(); read(Q); int tin; while(Q--) { //printf("Q=%d ",Q); scanf("%s",s); //printf("%c ",s[0]); read(tin); if(s[0]=='a') add(tin); else if(s[0]=='d') del(tin); else { ans=0; vv=tin; limit=0; while((1<<limit)&vv) ++limit; --limit; dfs(root,15); printf("%d ",ans); } } }
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #include <cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int #define pr(x) ((x)->pr) #define v(x) ((x)->v) #define nx(x) ((x)->nx) using namespace std; inline void read(int &x) { x=0; char q=getchar(); while(q<'0'||q>'9') q=getchar(); while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar(); } int Q; int tin; char s[10]; int con[(1<<16)+100]; int main(){ rint i; int ans; read(Q); while(Q--) { scanf("%s",s); read(tin); if(s[0]=='a') ++con[tin]; else if(s[0]=='d') --con[tin]; else { ans=0; for(i=tin;i;i=(i-1)&tin) ans+=con[i]; ans+=con[0]; printf("%d ",ans); } } }
#pragma GCC optimize("O3") #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #include <cmath> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long #define rint register int #define pr(x) ((x)->pr) #define v(x) ((x)->v) #define nx(x) ((x)->nx) using namespace std; inline void read(int &x) { x=0; char q=getchar(); while(q<'0'||q>'9') q=getchar(); while(q>='0'&&q<='9') x=x*10+q-'0',q=getchar(); } int Q; int tin; char s[10]; int f[(1<<8)+10][(1<<8)+10]; int main(){ //freopen("T3.in","r",stdin); rint i; int ans,maxp,pr,su,tt; maxp=(1<<8)-1; read(Q); while(Q--) { scanf("%s",s); read(tin); pr=tin&maxp; su=tin>>8; if(s[0]=='a') { tt=((~su)&maxp); for(i=tt;i;i=(i-1)&tt) ++f[pr][(~i)&maxp]; ++f[pr][maxp]; } else if(s[0]=='d') { tt=((~su)&maxp); for(i=tt;i;i=(i-1)&tt) --f[pr][(~i)&maxp]; --f[pr][maxp]; } else { ans=f[0][su]; for(i=pr;i;i=(i-1)&pr) ans+=f[i][su]; printf("%d ",ans); } } }