链接:http://bestcoder.hdu.edu.cn/
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 105 #define Mm 200 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; int a[1005]; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } if(n==1) cout<<a[1]<<endl; else cout<<0<<endl; } return 0; }
先判断能否组成回文串,显然奇数个的字符大于1时不能组成回文串,然后组合数求,注意要用逆元或费马小。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 10005 #define Mm 200 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; int a[1005]; ll fac[1010]; ll ppow(ll k,ll n) { ll c=1; while(n) { if(n%2) c=(c*k)%mod; k=(k*k)%mod; n>>=1; } return c; } ll C(int a,int b) { return (((fac[b]*ppow((fac[a]*fac[b-a])%mod,mod-2)))%mod)%mod; } int num[Mn]; int main() { int t; fac[0]=1; for(int i=1;i<1010;i++) { fac[i]=(fac[i-1]*i)%mod; } scanf("%d",&t); while(t--) { string s; cin>>s;CLR(num,0); for(int i=0;i<s.size();i++) { num[s[i]-'a']++; } int flag=0; for(int i=0;i<26;i++) { if(num[i]%2) flag++; num[i]/=2; } ll ans=1; if(flag>1) cout<<0<<endl; else { int l=s.size()/2; for(int i=0;i<26;i++) { if(num[i]==0) continue; ans=(ans*C(num[i],l))%mod; l-=num[i]; } cout<<ans<<endl; } } return 0; }
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 505 #define Mm 2000005 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; int g[Mn*Mn]; int x[Mn*Mn],y[Mn*Mn]; int pre[Mn*Mn]; int n,m; int way[4][2]={0,-1,-1,0,1,0,0,1}; int find(int x) { return x==pre[x]?pre[x]:pre[x]=find(pre[x]); } void ol(int x,int y) { int a=find(x); int b=find(y); if(a!=b) pre[a]=b; } int main() { int t; scanf("%d",&t); while(t--) { string s; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { cin>>s; for(int j=0;j<m;j++) { g[i*m+j]=s[j]-'0'; pre[i*m+j]=i*m+j; } } int k,ans=0; scanf("%d",&k); for(int i=1;i<=k;i++) { scanf("%d%d",&x[i],&y[i]); g[x[i]*m+y[i]]=1; } int ss=n*m,tt=ss+1; pre[ss]=ss;pre[tt]=tt; for(int i=0;i<m;i++) if(!g[i])ol(ss,i); for(int i=(n-1)*m;i<m*n;i++) if(!g[i])ol(tt,i); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { //cout<<g[i*m+j]; if(!g[i*m+j]) { for(int v=0;v<4;v++) { int xx=i+way[v][0]; int yy=j+way[v][1]; int pos=xx*m+yy; if(yy<0||yy>=m||xx<0||xx>=n||g[pos]) continue; ol(i*m+j,pos); } } } } if(find(ss)==find(tt)) { cout<<-1<<endl; continue; } for(int i=k;i>=1;i--) { g[x[i]*m+y[i]]=0; if(x[i]==0) ol(ss,x[i]*m+y[i]); else if(x[i]==n-1) ol(tt,x[i]*m+y[i]); for(int v=0;v<4;v++) { int xx=x[i]+way[v][0]; int yy=y[i]+way[v][1]; int pos=xx*m+yy; if(yy<0||yy>=m||xx<0||xx>=n||g[pos]) continue; ol(x[i]*m+y[i],pos); } if(find(ss)==find(tt)) { ans=i; break; } } cout<<ans<<endl; } return 0; }
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 2010 #define Mm 2000005 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; int a[Mn]; double dp[Mn]; int main() { int t,n,m,x; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); CLR(a,0); for(int i=1;i<=m;i++) { scanf("%d",&x); a[x+1]=1; } CLR(dp,0); for(int i=1;i<=n;i++) { int flag=0; for(int j=i;j>0;j--) { if(a[j]) flag++; if(flag>1) break; if(flag==1) dp[i]=max(dp[i],dp[j-1]+log2(i-j+1)); } } printf("%.0f\n",floor(1000000.0*dp[n])); } return 0; }
pre[i]设为 n。 这样对于一个查询 [L, R], 我们只需要计算出 在这个区间内有多少个三元组的 pre 值是小于 L 的。 到这里,就可以使用可持久化线段树来计算了。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 200005 #define Mm 4000005 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; struct node { int x,y,z,w; node(){} node(int x,int y,int z,int w):x(x),y(y),z(z),w(w){} }p[Mn]; bool cmp(node a,node b) { if(a.x!=b.x) return a.x<b.x; if(a.y!=b.y) return a.y<b.y; if(a.z!=b.z) return a.z<b.z; return a.w<b.w; } int tot=0; int root[Mn],ls[Mm],rs[Mm],sum[Mm]; void Insert(int l,int r,int x,int &y,int val) { y=++tot; sum[y]=sum[x]+1; if(l==r) return ; ls[y]=ls[x],rs[y]=rs[x]; int mid=(l+r)>>1; if(val<=mid) Insert(l,mid,ls[x],ls[y],val); else Insert(mid+1,r,rs[x],rs[y],val); } int ask(int l,int r,int x,int y,int k) { if(l==r) return sum[y]-sum[x]; int mid=(l+r)>>1; if(mid>=k) return ask(l,mid,ls[x],ls[y],k); else return sum[ls[y]]-sum[ls[x]]+ask(mid+1,r,rs[x],rs[y],k); } int fl[Mn]; int pre[Mn]; int b[Mn]; int a[Mn]; int main() { int t;scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n-2;i++) p[i]=node(a[i],a[i+1],a[i+2],i); sort(p+1,p+n-1,cmp); p[0].x=p[0].y=p[0].z=p[0].w=-1; int cnt=0; for(int i=1;i<=n-2;i++) { if(p[i].x<=p[i].y&&p[i].y<=p[i].z) { if(p[i].x!=p[i-1].x||p[i].y!=p[i-1].y||p[i].z!=p[i-1].z) fl[p[i].w]=++cnt; else fl[p[i].w]=cnt; } else fl[p[i].w]=0; } CLR(b,0); sum[0]=root[0]=ls[0]=rs[0]=tot=0; for(int i=1;i<=n-2;i++) { if(!fl[i]) pre[i]=n; else pre[i]=b[fl[i]]+1;b[fl[i]]=i; Insert(1,n,root[i-1],root[i],pre[i]); } int m; scanf("%d",&m); while(m--) { int l,r; scanf("%d%d",&l,&r); if(r-l<2) printf("0\n"); else printf("%d\n",ask(1,n,root[l-1],root[r-2],l)); } } return 0; }