csp-s analog test group b snacks antipalindome, randomwalking, string Interpretations

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;
}

 

Guess you like

Origin www.cnblogs.com/Juve/p/11599329.html