zoukankan      html  css  js  c++  java
  • XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia

    1. GUI

    按题意判断即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
    const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
    int casenum, casei;
    bool inclu(int L, int R, int l, int r)
    {
    	return L <= l && r <= R;
    }
    int main()
    {
    	scanf("%d", &casenum);
    	for (casei = 1; casei <= casenum; ++casei)
    	{
    		int x1, x2, x3, x4;
    		int y1, y2, y3, y4;
    		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    		scanf("%d%d%d%d",&x3,&y3,&x4,&y4);
    		if(inclu(x1,x2,x3,x4) && inclu(y1,y2,y3,y4))
    		{
    			puts("B in A");
    		}
    		else if(inclu(x3,x4,x1,x2) && inclu(y3,y4,y1,y2))
    		{
    			puts("A in B");
    		}
    		else if((x2 < x3 || x4 < x1) || (y2 < y3 || y4 < y1))
    		{
    			puts("Separate");
    		}
    		else puts("Intersect");
    	}
    	return 0;
    }
    /*
    【trick&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

    2. Searching on the Cube

    首先爬山找到一个极小点,然后不断前进找到另一个极小点,分析哪一个是答案即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
    const int N = 0, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
    int casenum, casei;
    int n;
    char rtn[100];
    void fwd()
    {
    	puts("forward");
    	fflush(stdout);
    	scanf("%s", rtn);
    }
    void rgt()
    {
    	puts("right");
    	fflush(stdout);
    }
    void lft()
    {
    	puts("left");
    	fflush(stdout);
    }
    void dig()
    {
    	puts("dig");
    	fflush(stdout);
    	exit(0);
    }
    bool BEST()
    {
    	fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		return 0;
    	}
    	lft(); lft(); fwd();
    	fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		return 0;
    	}
    	lft(); lft(); fwd();
    	lft(); fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		return 0;
    	}
    	lft(); lft(); fwd();
    	fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		return 0;
    	}
    	lft(); lft(); fwd();
    	return 1;
    }
    bool onlycheckBEST()
    {
    	bool flag = 1;
    	fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		flag = 0;
    	}
    	lft(); lft(); fwd(); lft(); lft();
    	if(!flag)return 0;
    	
    	lft(); fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		flag = 0;
    	}
    	lft(); lft(); fwd(); lft();
    	if(!flag)return 0;
    	
    	rgt(); fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		flag = 0;
    	}
    	lft(); lft(); fwd(); rgt();
    	if(!flag)return 0;
    	
    	lft(); lft(); fwd();
    	if(strcmp(rtn, "closer") == 0)
    	{
    		flag = 0;
    	}
    	lft(); lft(); fwd();
    	if(!flag)return 0;
    	return 1;
    }
    int main()
    {
    	while(!BEST());
    	int clo = 0;
    	int far = 0;
    	while(1)
    	{
    		fwd();
    		if(strcmp(rtn, "closer") == 0)
    		{
    			++clo;
    		}
    		else if(strcmp(rtn, "farther") == 0)
    		{
    			++far;
    		}
    		if(onlycheckBEST())
    		{
    			if(clo >= far)
    			{
    				dig();
    			}
    			else clo = far = 0;
    		}
    	}
    	return 0;
    }
    
    /*
    【trick&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

    3. Mirrors

    留坑。

    4. Roads to cinematography

    $1$和$n$的最优连法一定是$1$往下,$n$往左,中间必然存在一个点$i$满足$i$往左到$1$,$i+1$往下到$n$。

    设$f[l][r]$表示$l$往下,$r$往左时,$[l,r]$的最优连法,枚举$i$转移即可。

    时间复杂度$O(n^3)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=505,inf=1000000000;
    int n,i,j,m,e[100010][4];
    int f[N][N],g[N][N];bool v[N][N];
    struct P{int x,y;}a[N];
    inline void add(int x1,int y1,int x2,int y2){
    	if(x1<x2)swap(x1,x2),swap(y1,y2);
    	if(y1<y2)swap(x1,x2),swap(y1,y2);
    	if(x1==x2&&y1==y2)return;
    	m++;
    	e[m][0]=x1;
    	e[m][1]=y1;
    	e[m][2]=x2;
    	e[m][3]=y2;
    }
    void dfs(int l,int r){
    	if(l+1>=r)return;
    	if(v[l][r])return;
    	v[l][r]=1;
    	f[l][r]=inf;
    	for(int i=l;i<r;i++){
    		//i left,i+1 down
    		dfs(l,i);
    		dfs(i+1,r);
    		int t=f[l][i]+f[i+1][r]+a[i].x-a[l].x+a[i+1].y-a[r].y;
    		if(t<f[l][r]){
    			f[l][r]=t;
    			g[l][r]=i;
    		}
    	}
    }
    void go(int l,int r){
    	if(l+1>=r)return;
    	int i=g[l][r];
    	go(l,i);
    	go(i+1,r);
    	add(a[l].x,a[i].y,a[i].x,a[i].y);
    	add(a[i+1].x,a[r].y,a[i+1].x,a[i+1].y);
    }
    int main(){
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
    	dfs(1,n);
    	f[1][n]+=a[1].x+a[1].y+a[n].x-a[1].x;
    	add(0,0,a[1].x,0);
    	add(a[1].x,0,a[1].x,a[1].y);
    	add(a[1].x,a[n].y,a[n].x,a[n].y);
    	go(1,n);
    	printf("%d %d
    ",m,f[1][n]);
    	for(i=1;i<=m;i++){for(j=0;j<4;j++)printf("%d ",e[i][j]);puts("");}
    }
    

      

    5. Geometric solver

    按题意模拟。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    void fre() {  }
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
    const int N = 2e5 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
    int casenum, casei;
    int n, m;
    int id[N];
    int root[N];
    int col[N];
    bool edge[N];
    vector<int>ans;
    bool FLAG;
    struct A
    {
    	int y;
    	int tp;
    	int id;
    };
    vector< A >a[N];
    void dfs(int x)
    {
    	for(auto it : a[x])
    	{
    		int y = it.y;
    		int tp = it.tp;
    		int id = it.id;
    		if(col[y] == -1)
    		{
    			col[y] = col[x] ^ tp;
    			edge[id] = 1;
    			dfs(y);
    		}
    		else
    		{
    			if(!edge[id])
    			{
    				edge[id] = 1;
    				ans.push_back(it.id);
    				//printf("!edge[id]: %d
    ", id);
    			}
    			if(col[y] != (col[x] ^ tp))
    			{
    				FLAG = 0;
    			}
    		}
    	}
    }
    int main()
    {
    	while(~scanf("%d%d",&n, &m))
    	{
    		MS(edge, 0);
    		MS(root, -1);
    		MS(id, -1);
    		ans.clear();
    		for(int i = 1; i <= n; ++i)
    		{
    			a[i].clear();
    		}
    		FLAG = 1;
    		for(int i = 1; i <= m; ++i)
    		{
    			char op[100];
    			scanf("%s", op);
    			if(op[0] == 'v')
    			{
    				int x; scanf("%d", &x);
    				if(root[x] == 0)
    				{
    					ans.push_back(i);
    					//printf("root[x] == 0: %d
    ", i);
    				}
    				else if(root[x] == 1)
    				{
    					FLAG = 0;
    				}
    				else
    				{
    					root[x] = 0;
    					id[x] = i;
    				}
    			}
    			else if(op[0] == 'h')
    			{
    				int x; scanf("%d", &x);
    				if(root[x] == 1)
    				{
    					ans.push_back(i);
    					//printf("root[x] == 1: %d
    ", i);
    				}
    				else if(root[x] == 0)
    				{
    					FLAG = 0;
    				}
    				else
    				{
    					root[x] = 1;
    					id[x] = i;
    				}
    			}
    			else 
    			{
    				int x, y;
    				scanf("%d%d", &x, &y);
    				if(op[1] == 'e')//be horizontal
    				{
    					a[x].push_back({y, 1, i});	
    					a[y].push_back({x, 1, i});
    				}
    				else
    				{
    					a[x].push_back({y, 0, i});
    					a[y].push_back({x, 0, i});
    				}
    			}
    		}
    		MS(col, -1);
    		int useful = 0;
    		for(int i = 1; i <= n; ++i)
    		{
    			if(root[i] != -1)
    			{
    				if(col[i] == -1)
    				{
    					col[i] = root[i];
    					dfs(i);
    					++useful;
    				}
    				else
    				{
    					if(col[i] != root[i])
    					{
    						FLAG = 0;
    					}
    					ans.push_back(id[i]);
    					//printf("same_con: %d
    ", id[i]);
    				}
    			}
    		}
    		for(int i = 1; i <= n; ++i)
    		{
    			if(col[i] == -1)
    			{
    				col[i] = 0;
    				dfs(i);
    			}
    		}
    		if(!FLAG)
    		{
    			puts("inconsistent");
    		}
    		else
    		{
    			puts("consistent");
    			printf("%d
    ", ans.size());
    			int sz = ans.size();
    			for(int i = 0; i < sz; ++i)
    			{
    				printf("%d%c", ans[i], i == sz - 1 ? '
    ' : ' ');
    			}		
    		}
    	}
    	return 0;
    }
    
    /*
    【trick&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

    6. Monsters

    设$f[i]=max(f[i-1],s[i])$,则$ans=prodmin(m[i],f[i])$。

    线段树维护每个区间$[l,r]$内只考虑区间$[l,r]$时以下信息:

    • $fl,fr$:$f[l]$和$f[r]$的值。
    • $mul$:$prodmin(m[i],f[i])$。
    • $rmul$:将右儿子用左儿子的$f$修正后右儿子的贡献。

    对于$mul$,有$mul=左儿子的mul imes ask(右儿子,左儿子的f[r])$。

    其中$ask(x,pre)$表示考虑$x$的子树,之前$f$为$pre$时的乘积:

    • 若$flgeq pre$,则无需修正,直接返回$mul$即可。
    • 若$x$为叶子,则暴力处理即可。
    • 若左儿子的$frgeq pre$,则右儿子只会被左儿子修正,返回$ask(左儿子,pre) imes rmul$即可。
    • 否则左儿子将全部被修正为$pre$,故返回$ask(右儿子,pre) imes 左儿子全部修正为pre$的贡献即可。而贡献可以在每个节点套上一棵Treap来$O(log n)$计算。

    总时间复杂度$O(nlog^3n)$。

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    const int N=100010,M=262150,P=1000000007;
    int fl[M],fr[M],mul[M],rmul[M];
    int n,_,i,s[N],m[N];
    int CNT,MUL,ni;
    struct node{
    	int val,cnt,sum,v,mul,p;
    	node*l,*r;
    	node(){
    		val=cnt=sum=p=0;
    		v=mul=1;
    		l=r=NULL;
    	}
    	void up(){
    		sum=cnt+l->sum+r->sum;
    		mul=1LL*v*l->mul%P*r->mul%P;
    	}
    }*blank=new(node),*T[M],pool[5000000],*cur=pool;
    inline void Rotl(node*&x){node*y=x->r;x->r=y->l;x->up();y->l=x;y->up();x=y;}
    inline void Rotr(node*&x){node*y=x->l;x->l=y->r;x->up();y->r=x;y->up();x=y;}
    void Ins(node*&x,int p){
    	if(x==blank){
    		x=cur++;
    		x->val=p;
    		x->l=x->r=blank;
    		x->cnt=x->sum=1;
    		x->v=x->mul=p;
    		x->p=rand();
    		return;
    	}
    	x->sum++;
    	x->mul=1LL*x->mul*p%P;
    	if(p==x->val){
    		x->cnt++;
    		x->v=1LL*x->v*p%P;
    		return;
    	}
    	if(p<x->val){
    		Ins(x->l,p);
    		if(x->l->p>x->p)Rotr(x);
    	}else{
    		Ins(x->r,p);
    		if(x->r->p>x->p)Rotl(x);
    	}
    }
    void Del(node*&x,int p,int q){
    	x->sum--;
    	x->mul=1LL*x->mul*q%P;
    	if(p==x->val){
    		x->cnt--;
    		x->v=1LL*x->v*q%P;
    		return;
    	}
    	if(p<x->val){
    		Del(x->l,p,q);
    		if(x->l->p>x->p)Rotr(x);
    	}else{
    		Del(x->r,p,q);
    		if(x->r->p>x->p)Rotl(x);
    	}
    }
    void Ask(node*&x,int p){//<p
    	if(x==blank)return;
    	if(p==x->val){
    		CNT+=x->l->sum;
    		MUL=1LL*MUL*x->l->mul%P;
    		return;
    	}
    	if(p<x->val){
    		Ask(x->l,p);
    		return;
    	}
    	Ask(x->r,p);
    	CNT+=x->l->sum+x->cnt;
    	MUL=1LL*MUL*x->l->mul%P*x->v%P;
    }
    inline int po(int a,int b){
    	int t=1;
    	for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;
    	return t;
    }
    void build(int x,int a,int b){
    	if(a<b){
    		int mid=(a+b)>>1;
    		build(x<<1,a,mid);
    		build(x<<1|1,mid+1,b);
    	}
    	int i;
    	fl[x]=fr[x]=s[a];
    	mul[x]=1;
    	T[x]=blank;
    	for(i=a;i<=b;i++){
    		fr[x]=max(fr[x],s[i]);
    		mul[x]=1LL*mul[x]*min(fr[x],m[i])%P;
    		Ins(T[x],m[i]);
    	}
    	if(a<b)rmul[x]=1LL*mul[x]*po(mul[x<<1],P-2)%P;
    }
    inline int query(int x,int a,int b,int pre){
    	CNT=0;
    	MUL=1;
    	Ask(T[x],pre);
    	return 1LL*MUL*po(pre,b-a+1-CNT)%P;
    	//int t=1;
    	//for(int i=a;i<=b;i++)t=1LL*t*min(m[i],pre)%P;
    	//return t;
    }
    int ask(int x,int a,int b,int pre){
    	if(fl[x]>=pre)return mul[x];
    	if(a==b)return min(m[a],pre);
    	int mid=(a+b)>>1;
    	if(fr[x<<1]>=pre)return 1LL*ask(x<<1,a,mid,pre)*rmul[x]%P;
    	return 1LL*query(x<<1,a,mid,pre)*ask(x<<1|1,mid+1,b,pre)%P;
    }
    inline void up(int x,int a,int b){
    	fl[x]=fl[x<<1];
    	fr[x]=max(fr[x<<1],fr[x<<1|1]);
    	int mid=(a+b)>>1;
    	mul[x]=1LL*mul[x<<1]*ask(x<<1|1,mid+1,b,fr[x<<1])%P;
    	rmul[x]=1LL*mul[x]*po(mul[x<<1],P-2)%P;
    }
    void change(int x,int a,int b,int c){
    	if(a==b){
    		fl[x]=fr[x]=s[a];
    		mul[x]=min(s[a],m[a]);
    		return;
    	}
    	int mid=(a+b)>>1;
    	if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
    	up(x,a,b);
    }
    void changem(int x,int a,int b,int c,int A,int B){
    	Ins(T[x],B);
    	Del(T[x],A,ni);
    	if(a==b)return;
    	int mid=(a+b)>>1;
    	if(c<=mid)changem(x<<1,a,mid,c,A,B);else changem(x<<1|1,mid+1,b,c,A,B);
    }
    int main(){
    	blank->l=blank->r=blank;
    	scanf("%d%d%d",&n,&_,&s[1]);
    	for(i=1;i<=n;i++)scanf("%d",&m[i]);
    	for(i=2;i<=n+1;i++)scanf("%d",&s[i]);
    	build(1,1,n);
    	//shutaoshu
    	printf("%d
    ",mul[1]);
    	while(_--){
    		int op,x,y;
    		scanf("%d%d%d",&op,&x,&y);
    		if(op==0){
    			ni=po(m[x],P-2);
    			changem(1,1,n,x,m[x],y);
    			m[x]=y;
    			change(1,1,n,x);
    		}else{
    			x++;
    			if(x<=n){
    				s[x]=y;
    				change(1,1,n,x);
    			}
    		}
    		printf("%d
    ",mul[1]);
    	}
    }
    

      

    7. Regular expressions

    注意到$((a(c|(g|t)))*)$可以匹配所有字符串,所以答案不超过$16$。

    爆搜出所有短正则表达式后,建立DFA,最小化DFA判断即可。

    8. WSO-2017 soccer team

    假设所有人都选择$2a[i]$,那么需要选出$k=frac{r-l+1}{3}$个人增加$2(d[i]-a[i])$,还需要再选出$k$个人增加$d[i]-a[i]$,故可持久化线段树维护区间$k$小值即可。

    时间复杂度$O(nlog n)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=129000,M=N*21;
    int n,m,i,x,y;
    ll a[N],d[N],sa[N],c[N];
    int T[N],tot,l[M],r[M],cnt[M];ll sum[M];
    int ins(int x,int a,int b,int c,ll p){
    	int y=++tot;
    	cnt[y]=cnt[x]+1;
    	sum[y]=sum[x]+p;
    	if(a==b)return y;
    	int mid=(a+b)>>1;
    	if(c<=mid)l[y]=ins(l[x],a,mid,c,p),r[y]=r[x];
    	else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c,p);
    	return y;
    }
    inline ll kth(int x,int y,int k){
    	if(!k)return 0;
    	int a=1,b=n,mid;ll ans=0;
    	while(a<b){
    		mid=(a+b)>>1;
    		int t=cnt[l[x]]-cnt[l[y]];
    		if(t>=k){
    			b=mid;
    			x=l[x];
    			y=l[y];
    		}else{
    			k-=t;
    			ans+=sum[l[x]]-sum[l[y]];
    			a=mid+1;
    			x=r[x];
    			y=r[y];
    		}
    	}
    	if(k)ans+=(sum[x]-sum[y])/(cnt[x]-cnt[y])*k;
    	return ans;
    }
    inline ll ask(int x,int y,int l,int r){return kth(x,y,r)-kth(x,y,l-1);}
    int main(){
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)scanf("%lld",&a[i]),sa[i]=sa[i-1]+a[i];
    	for(i=1;i<=n;i++)scanf("%lld",&d[i]);
    	for(i=1;i<=n;i++)c[i]=d[i]-a[i];
    	sort(c+1,c+n+1);
    	for(i=1;i<=n;i++)T[i]=ins(T[i-1],1,n,lower_bound(c+1,c+n+1,d[i]-a[i])-c,d[i]-a[i]);
    	scanf("%d",&m);
    	while(m--){
    		scanf("%d%d",&x,&y);
    		ll ans=(sa[y]-sa[x-1])*2;
    		int len=(y-x+1)/3;
    		ans+=ask(T[y],T[x-1],len*2+1,len*3)*2;
    		ans+=ask(T[y],T[x-1],len+1,len*2);
    		printf("%lld.%lld
    ",ans/2,ans%2*5);
    	}
    }
    

      

    9. Primitive divisors

    枚举所有的质数$p$,满足$q^nmod p=1$的$p$不会很多,对于每个将$varphi(p)$分解质因数找到最小循环节判断即可。

    #include<cstdio>
    const int N=10000000;
    int n,q,tot,i,j,p[N],ans[N],fin,v[N];
    inline int po(int a,int b,int P){
    	int t=1;
    	for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;
    	return t;
    }
    inline bool check(int x){
    	if(x<=n)return 0;
    	if(po(q,n,x)!=1)return 0;
    	int per=x-1;
    	int t=per;
    	while(t>1){
    		int o=v[t];
    		if(po(q,per/o,x)==1)per/=o;
    		if(n>per)return 0;
    		t/=o;
    	}
    	return 1;
    }
    int main(){
    	scanf("%d%d",&q,&n);
    	for(i=2;i<N;i++){
    		if(!v[i]){
    			p[tot++]=i;
    			v[i]=i;
    		}
    		for(j=0;j<tot&&1LL*i*p[j]<N;j++){
    			v[i*p[j]]=p[j];
    			if(i%p[j]==0)break;
    		}
    	}
    	for(i=0;i<tot;i++)if(check(p[i]))ans[++fin]=p[i];
    	printf("%d
    ",fin);
    	for(i=1;i<=fin;i++)printf("%d ",ans[i]);
    }
    

      

    10. Tickets

    按题意模拟。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<ctype.h>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<algorithm>
    #include<time.h>
    using namespace std;
    void fre() {  }
    #define MS(x, y) memset(x, y, sizeof(x))
    #define ls o<<1
    #define rs o<<1|1
    typedef long long LL;
    typedef unsigned long long UL;
    typedef unsigned int UI;
    template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
    template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
    const int N = 1e6 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
    template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
    int casenum, casei;
    int n;
    char a[N], b[N];
    int main()
    {
    	while(~scanf("%s%s",a,b))
    	{
    		int n = strlen(a);
    		int A = 0, B = 0;
    		for(int i = 0; i < n; ++i)
    		{
    			if(a[i] < b[i])++A;
    			else if(a[i] > b[i])++B;
    		}
    		printf("%d
    %d
    ",A,B);
    	}
    	return 0;
    }
    
    /*
    【trick&&吐槽】
    
    
    【题意】
    
    
    【分析】
    
    
    【时间复杂度&&优化】
    
    
    */
    

      

    11. Logarithm smoothing

    二分答案$mid$,将$f(x)=cln x$的图像往上下分别平移$mid$。

    从$(a,f(a)+mid)$开始往右沿着切线走,判断走$n$步是否可以到达$b$之后的位置即可。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long double ld;
    const int T=50;
    int n;ld C,A,B,OFFSET;
    void read(ld&x){
    	double t;
    	scanf("%lf",&t);
    	x=t;
    }
    void write(ld x){
    	printf("%.15f",(double)x);
    }
    bool down(ld A,ld B,int n);
    bool up(ld A,ld B,int n){
    	//printf("up %d
    ",n);
    	if(A>=B)return 1;
    	if(n<1)return 0;
    	ld y=C*log(A)+OFFSET;
    	//f'(x)=C/x
    	ld L=A,R=B+10;
    	for(int i=0;i<T;i++){
    		ld mid=(L+R)/2;
    		if((C*log(mid)-OFFSET-y)/(mid-A)<C/mid)L=mid;else R=mid;
    	}
    	return down(L,B,n);
    }
    bool down(ld A,ld B,int n){
    	//printf("down %d
    ",n);
    	if(A>=B)return 1;
    	if(n<1)return 0;
    	ld y=C*log(A)-OFFSET;
    	//f'(x)=C/x
    	ld k=C/A;
    	ld L=A,R=B+10;
    	for(int i=0;i<T;i++){
    		ld mid=(L+R)/2;
    		if(y+(mid-A)*k<C*log(mid)+OFFSET)L=mid;else R=mid;
    	}
    	return up(L,B,n-1);
    }
    bool check(ld _mid){
    	OFFSET=_mid;
    	if(down(A,B,n))return 1;
    	if(up(A,B,n))return 1;
    	return 0;
    }
    int main(){
    	int Case;
    	scanf("%d",&Case);
    	while(Case--){
    		scanf("%d",&n);
    		read(C);
    		read(A);
    		read(B);
    		ld l=0,r=C*(log(B)-log(A))/2;
    		for(int i=0;i<100;i++){
    			ld mid=(l+r)/2;
    			if(check(mid))r=mid;else l=mid;
    		}
    		write(l);
    		puts("");
    	}
    }
    

      

    12. Outer space signals

    KMP求出两个串最左和最右出现位置然后判断即可。

    时间复杂度$O(n)$。

    #include<cstdio>
    #include<cstring>
    const int N=1000010;
    int Case,na,nb,nc,i,bl,br,cl,cr;char a[N],b[N],c[N];
    int nxt[N];
    void solve(int n,char*a,int m,char*b,int&l,int&r){
      int i,j;
      for(nxt[1]=j=0,i=2;i<=n;nxt[i++]=j){
        while(j&&a[j+1]!=a[i])j=nxt[j];
        if(a[j+1]==a[i])j++;
      }
      l=r=0;
      for(i=1,j=0;i<=m;i++){
        while(j&&a[j+1]!=b[i])j=nxt[j];
        if(a[j+1]==b[i])j++;
        if(j==n){
          if(!l)l=i;
          r=i;
          j=nxt[j];
        }
      }
    }
    bool check(){
      if(!bl||!cl)return 0;
      if(cr-nc+1>bl)return 1;
      if(br-nb+1>cl)return 1;
      return 0;
    }
    int main(){
      scanf("%d",&Case);
      while(Case--){ 
        scanf("%s%s%s",a+1,b+1,c+1);
        na=strlen(a+1);
        nb=strlen(b+1);
        nc=strlen(c+1);
        solve(nb,b,na,a,bl,br);
        solve(nc,c,na,a,cl,cr);
        puts(check()?"YES":"NO");
      }
    }
    

      

  • 相关阅读:
    排列专题(不定期更新)
    搜索专题(不定期更新)
    Redis 高级面试题
    面试题1
    CentOS7查看开放端口命令及开放端口号
    Union和Union All到底有什么区别
    浅谈MySQL中优化sql语句查询常用的30种方法
    什么是分布式系统,如何学习分布式系统(转)
    浅析分布式系统(转)
    什么是分布式系统(通俗易懂的说法)(转)
  • 原文地址:https://www.cnblogs.com/clrs97/p/8626131.html
Copyright © 2011-2022 走看看