• 7.24 第四次多校


    1001_hdu5763
    听说有人没用kmp直接平方过了(摔)

    /*令dp[i]表示到i结尾的字符串可以表示的不同含义数,那么考虑两种转移:
    末尾不替换含义:dp[i - 1]
    末尾替换含义:dp[i - |B|]  (A.substr(i - |B| + 1,|B|) = B)
    那么对于末尾替换含义的转移,需要快速判断BB能不能和当前位置的后缀匹配,kmp或者hash判断即可。
    复杂度:O(N)*/ 
    //cww97
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=100007;
    const int P=1000000007;
    char a[N],b[N];
    bool mat[N];
    int next[N];
    ll f[N];
    
    void getNext(int m){
    	int i=0,j=-1;
    	next[0]=-1;
    	while (i<m){
    		if (j==-1||b[i]==b[j]){
    			if (b[++i]!=b[++j])next[i]=j;
    			else next[i]=next[j];
    		}else j=next[j];
    	}
    }
    
    void KMP(int n,int m){
    	memset(mat,0,sizeof(mat));
    	int i=0,j=0;
    	getNext(m);
    	while (i<n&&j<m){
    		if (j==-1||a[i]==b[j])i++,j++;
    		else j=next[j];
    		if (!i&&!j)break;
    		if (j==m){
    			mat[i]=1;
    			//printf("mat[%d]get
    ",i);
    			j=next[j];
    		}
    	}
    }
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	int T;
    	scanf("%d
    ",&T);
    	for (int cas=1;cas<=T;cas++){
    		scanf("%s%s",a,b);
    		int n=strlen(a);
    		int m=strlen(b);
    		KMP(n,m);
    		memset(f,0,sizeof(f));
    		f[0]=1;
    		for (int i=1;i<=n+1;i++){
    			if (mat[i])f[i]=(f[i-m]+f[i-1])%P;
    			else f[i]=(f[i-1])%P;
    			//printf("f[%d]=%d
    ",i,f[i]);
    		}
    		printf("Case #%d: %I64d
    ",cas,f[n]%P);
    	}
    	return 0;
    }
    

    1010_hdu5773
    复制下cw的讲解:
    很巧妙的智商题。意思是数列里的 0 可以替换成任何数。做法很巧妙,如果 a1 ai 中有 z 个 0 的话,就把 ai 当作 ai − z 处理。遇到 0 不处理,最后把答案数加上总的 0 的个数即可

    #include<cstdio>
    using namespace std;
    const int N=1000010;
    int s[N],top,num;
    
    int Find(int x){
    	int l=1,r=top;
    	while (l<r){
    		int mid=(l+r)>>1;
    		if (s[mid]<=x)l=mid+1;
    		else r=mid;
    	}
    	return l;
    }
    
    int main(){
    	int T,n,x;
    	scanf("%d",&T);
    	for (int cas=1;cas<=T;cas++){
    		scanf("%d",&n);
    		num=0,top=0;
    		s[0]=-100000007;
    		for (;n--;){
    			scanf("%d",&x);
    			if (!x)num++;
    			else {
    				x-=num;
    				if (x>s[top]) s[++top]=x;
    				else s[Find(x)]=x;
    			}
    		}
    		printf("Case #%d: %d
    ",cas,top+num);
    	}
    	return 0;
    } 
    

    1011
    第一次见吧

    #include<cstdio>
    #include<map>
    #include<string>
    #include<iostream>
    using namespace std;
    map<string,int>mp;
    int a[100];
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	mp["Cleveland Cavaliers"]=0; a[0]=1;
    	mp["San Antonio Spurs"]=1;   a[1]=5;
    	mp["Miami Heat"]=2;          a[2]=3;
    	mp["Dallas Mavericks"]=3;    a[3]=1;
    	mp["L.A. Lakers"]=4;         a[4]=11;
    	mp["Boston Celtics"]=5;      a[5]=17;
    	mp["Detroit Pistons"]=7;     a[7]=3;
    	mp["Chicago Bulls"]=8;       a[8]=6;
    	mp["Houston Rockets"]=9;     a[9]=2;
    	mp["Philadelphia 76ers"]=10; a[10]=2;
    	mp["Seattle Sonics"]=11;     a[11]=1;
    	mp["Washington Bullets"]=12; a[12]=1;
    	mp["Portland Trail Blazers"]=13;a[13]=1;
    	mp["Golden State Warriors"]=14;a[14]=2;
    	mp["New York Knicks"]=15;    a[15]=2;
    	mp["Milwaukee Bucks"]=16;    a[16]=1;
    	mp["St. Louis Hawks"]=17;    a[17]=1;
    	mp["Philadelphia Warriors"]=18;a[18]=2;
    	mp["Syracuse Nats"]=19;      a[19]=1;
    	mp["Minneapolis Lakers"]=20; a[20]=5;
    	mp["Rochester Royals"]=21;   a[21]=1;
    	mp["Baltimore Bullets"]=22;  a[22]=1;
    	
    	int T,ans;
    	string st;
    	scanf("%d
    ",&T);
    	for (int cas=1;cas<=T;cas++){
    		getline(cin,st);
    		if (mp.find(st)==mp.end())ans=0;
    		else ans=a[mp[st]];
    		printf("Case #%d: %d
    ",cas,ans);
    	}
    	return 0;
    } 
    

    1012

    一开始跟队友同时交了一发abs(a[i]-i),,,T_T
    树状数组维护逆序对
    cw的讲解:
    问在冒泡排序中,每个数可能出现的最左位置和最右位置之差。最多往右移动次数其实就是这个数在当前位置时右边有多少个比它小的个数,这个倒过来做一遍即可,用树状数组维护。接着再排序一遍,在初始位置,最右位置,排序后的位置中分别找出最左和最右,然后算出答案。

    #include<cstdio> 
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=100010; 
    int a[N],c[N],l[N],r[N];
    int n;
    
    int sum(int x){
    	int s=0;
    	for (;x;x-=x&-x) s+=c[x];
    	return s;
    }
    
    void add(int x){
    	for (;x<=n;x+=x&-x) c[x]++;
    }
    
    int main(){
    	//freopen("fuck.in","r",stdin);
    	int T,x;
    	scanf("%d",&T);
    	for (int cas=1;cas<=T;cas++){
    		memset(c,0,sizeof(c));
    		scanf("%d",&n);
    		for (int i=1;i<=n;i++){
    			scanf("%d",&a[i]);
    			l[a[i]]=i;
    		}
    		for (int i=n;i;i--){
    			r[a[i]]=l[a[i]]+sum(a[i]-1);
    			add(a[i]);
    			l[a[i]]=min(a[i],i);
    			//printf("%d,l=%d,r=%d
    ",a[i],l[a[i]],r[a[i]]);
    		}
    		printf("Case #%d:",cas);
    		for (int i=1;i<=n;i++) {
    			printf(" %d",r[i]-l[i]);
    		}
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    P1772 [ZJOI2006]物流运输
    P4290 [HAOI2008]玩具取名
    P1859 不听话的机器人
    P1841 [JSOI2007]重要的城市
    P2182 翻硬币
    P1908 逆序对(归并排序)
    P1010 幂次方(分治)
    P3386 【模板】二分图匹配
    P2158 [SDOI2008]仪仗队
    P1582 倒水(贪心 + lowbit)
  • 原文地址:https://www.cnblogs.com/cww97/p/12349396.html
Copyright © 2020-2023  润新知