Questions surface: https://www.cnblogs.com/Juve/articles/11599318.html
antipalindome:
Hit the table to find the law?
For a palindrome string, as long as we do not within three palindromes can be, that they do not appear within three to legitimate palindrome
For the first three: m * (m-1) * (m-2), the remaining n-3 positions with m-2 to fill
Therefore $ ans = m * (m-1) * (m-2) ^ (n-2) $, noted that the boundary is determined
#include<iostream> #include<cstdio> #include<cstring> #define int long long using namespace std; const int mod=1e9+7; const int phi=1e9+6; int t,n,m,ans=0; int q_pow(int a,int b,int p){ a%=p; (b+=(p-1))%=(p-1); int res=1; while(b){ if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res%p; } signed main(){ scanf("%lld",&t); while(t--){ ans=0; scanf("%lld%lld",&n,&m); if(n==1){ printf("%lld\n",m%mod); continue; }else if(m==1){ puts("0"); continue; }else if(m==2&&n==2){ puts("2"); continue; }else{ ans=q_pow(m-2,n-2,mod)%mod; for(int i=m;i>=m-1;--i){ (ans*=(i%mod))%=mod; } printf("%lld\n",ans); } } return 0; }
randomwalking:
Tree dp, feel it troublesome thief, a blogger is not
#include<iostream> #include<cstdio> #include<cstring> #define int long long using namespace std; const int MAXN=1e6+4; const double inf=110000000000000000.0; int n,a[MAXN],du[MAXN],ans; int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],cnt=0; void add(int u,int v){ ++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt; } double f[MAXN],g[MAXN],minn=inf; void dfs(int x,int fa){ f[x]=(double)a[x]; if(du[x]==1&&fa!=0){ return ; } for(int i=pre[x];i;i=nxt[i]){ int y=to[i]; if(y==fa) continue; dfs(y,x); if(fa!=0&&du[x]!=1) f[x]+=(double)f[y]/(double)((double)du[x]-1.0); else f[x]+=(double)f[y]/du[x]; } } void DFS(int x,int fa){ for(int i=pre[x];i;i=nxt[i]){ int y=to[i]; if(y==fa) continue; g[y]=(double)a[y]; double tmp1=(double)(g[x]-(double)a[x])*(double)du[x]; double tmp2=tmp1-f[y]; double tmp3=(double)(f[y]-(double)a[y])*(double)(du[y]-1.0); if(du[x]>1) g[y]+=(double)(tmp2/(double)(du[x]-1.0)+(double)a[x]+tmp3)/(double)(du[y]); else g[y]+=(double)((double)a[x]+tmp3)/(double)(du[y]); DFS(y,x); } } signed main(){ scanf("%lld",&n); for(int i=1;i<=n;++i){ scanf("%lld",&a[i]); } for(int i=1,u,v;i<n;++i){ scanf("%lld%lld",&u,&v); add(u,v),add(v,u); ++du[u],++du[v]; } dfs(1,0); g[1]=f[1]; DFS(1,0); minn=g[1],ans=1; for(int i=1;i<=n;++i){ if(g[i]<minn){ ans=i; minn=g[i]; } } printf("%lld\n",ans); return 0; }
string:
First flip, and then maintain the same color difference-set position
26 and then into k binary number, can not be determined for the point of using 26 binary numbers to determine k
Interval inversion balanced tree
We give 'a' to 'z' is a number [1, 26], to give each of '?' A different reference numeral 26 is greater than the input string into a string of numbers such, the count
of S.
We direct this string of numbers to do the operation, get a new string of numbers, denoted by T.
this thing is this classic problem bzoj3223:. Tyvj1729 literary balanced tree
directly to the S and T, and with every check and set up, the reference numeral represents characters represent necessarily the same.
If a link comprising at least one letter in the block, then the characters are identified by China Unicom block.
otherwise, there are 26 possible, can be directly assigned to sweep over.
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<cmath> #define int long long using namespace std; const int MAXN=5e5+5; int n,m,k,l[MAXN],r[MAXN],b[MAXN]; char ch[MAXN]; bool pd[MAXN]; struct node1{ int val,pos; }a[MAXN]; int fa[MAXN]; int find(int x){ return fa[x]=(fa[x]==x?x:find(fa[x])); } void merge(int x,int y){ x=find(x),y=find(y); fa[max(x,y)]=min(x,y); } vector<int>v[MAXN]; int col[MAXN],tot=-1; struct Node{ bool rev; int s,h,v; Node *l,*r; }*root=0; struct tbw{ Node *l,*r; tbw(){} tbw(Node *a,Node *b){l=a,r=b;} }; int gets(Node *x){return x?x->s:0;} void update(Node *x){x->s=gets(x->l)+1+gets(x->r);} void rev(Node *x){ if(!x) return; x->rev ^=1; swap(x->l,x->r); } void down(Node *x){ if(x->rev) rev(x->l),rev(x->r),x->rev=0; } Node *merge(Node *a,Node *b){ if(!a) return b; if(!b) return a; if (a->h<b->h){ down(a); a->r=merge(a->r,b); update(a); return a; } down(b); b->l=merge(a,b->l); update(b); return b; } tbw split(Node *x,int k){ if(!x) return tbw(0,0); down(x); int tot=gets(x->l)+1; if(k<tot){ tbw a=split(x->l,k); x->l=a.r; update(x); return tbw(a.l,x); } tbw a=split(x->r,k-tot); x->r=a.l; update(x); return tbw(x,a.r); } void insert(int v){ Node *x=new Node; x->h=rand(),x->l=x->r=0; x->v=v,x->s=1; root=merge(root,x); } void rev(int l,int r){ tbw a=split(root,l-1); tbw b=split(a.r,r-l+1); rev(b.l); root=merge(merge(a.l,b.l),b.r); } int num=0; void print(Node *x){ if(!x) return; down(x); print(x->l); b[++num]=x->v; print(x->r); } signed main(){ scanf("%lld%lld%lld",&n,&m,&k); scanf("%s",ch+1); for(int i=1;i<=n;++i){ fa[i]=a[i].pos=b[i]=i; a[i].val=0; if(ch[i]!='?'){ a[i].val=ch[i]-'a'+1; pd[i]=1; } insert(i); } for(int i=1;i<=m;++i){ scanf("%lld%lld",&l[i],&r[i]); rev(l[i],r[i]); } print(root); for(int i=1;i<=n;++i){ merge(b[i],i); } for(int i=1;i<=n;++i){ int x=find(i); v[x].push_back(i); if(a[x].val!=0) col[x]=a[x].val; else if(a[i].val!=0) col[x]=a[i].val; } for(int i=1;i<=n;++i){ int x=find(i); if(col[x]==0) continue; a[i].val=col[x]; } for(int i=1;i<=n;++i){ if(col[i]==0&&v[i].size()!=0) ++tot; } for(int i=1;i<=n;++i){ int x=find(i); if(a[i].val!=0) continue; else if(x!=i) a[i].val=a[x].val; else if(tot>13) a[i].val=1,--tot; else{ int p=pow(26,tot--); int x=k/p; if(k%p) ++x; a[i].val=x--; k-=x*p; } } for(int i=1;i<=n;++i){ putchar(a[i].val+'a'-1); } puts(""); return 0; }