2012 ACM/ICPC Asia Regional Jinhua Online

来源:互联网 发布:下载卸载软件 编辑:程序博客网 时间:2024/05/18 19:37

//今天我们队一共出了三个题,1004,1008,1010,没出1006真是个悲剧大哭

 

//1004,枚举等号的位置后爆搜两边:

 

#include<stdio.h>#include<string.h>char str[20];int v,cnt,len;void find(int sum,int rem,int dep,int t){if(sum>1e8||rem>1e8)return;if(dep==len){if(sum+rem==t)cnt++;}else {if(rem)find(sum+rem,str[dep]-'0',dep+1,t);find(sum,rem*10+str[dep]-'0',dep+1,t);}}void dfs(int end,int dep,int rem,int sum){if(sum>1e8||rem>1e8)return;if(dep>end){find(0,0,dep,sum+rem);}else {dfs(end,dep+1,rem*10+str[dep]-'0',sum);if(rem)dfs(end,dep+1,str[dep]-'0',sum+rem);}}int main(){int i;while(scanf("%s",str)!=EOF){if(!strcmp(str,"END"))break;len=strlen(str);cnt=0;for(i=1;i<len;i++)dfs(i-1,0,0,0);printf("%d\n",cnt);}return 0;}


 

//1008:咋一看有点像线段树,搞了我们半天,也没想到lazy的地方,后面才想到用数论去搞,思路:开始对区间直接容斥筛选,因为m很小,后面就直接枚举改变的地方就好了;

 

#include<stdio.h>#include<string.h>#include<map>using namespace std;int vis[1000],prime[500],cnt;void init(){int i,j;memset(vis,0,sizeof(vis));for(i=2;i<100;i++)if(!vis[i])for(j=i+i;j<1000;j+=i)vis[j]=1;for(i=2,cnt=0;i<1000;i++)if(!vis[i])prime[cnt++]=i;}__int64 pri[100];__int64 get(__int64 n){__int64 i,j=0;for(i=0;n>=prime[i]&&i<cnt;i++){if(n%prime[i]==0){pri[j++]=prime[i];while(n%prime[i]==0){n/=prime[i];}}}if(n>1)pri[j++]=n;return j;}__int64 gcd(__int64 a,__int64 b){return b==0?a:gcd(b,a%b);}__int64 sum,flag;void yy(int p,int rem,int dep,int start,int end){__int64 i;__int64 tem;if(dep==0){tem=p/rem;if(flag)sum+=(tem+1)*tem*rem/2;else sum-=(tem+1)*tem*rem/2;}else {for(i=start;i<=end-dep+1;i++)yy(p,rem*pri[i],dep-1,i+1,end);}}void find(__int64 n,__int64 p){int i,j,len;if(n==0){sum=0;return;}len=get(p);sum=(1+n)*n/2;flag=0;for(i=1;i<=len;i++){yy(n,1,i,0,len-1);flag=(flag)?0:1;}}int main(){int cas,op;__int64 n,m,l,r,p,tem,k;init();scanf("%d",&cas);while(cas--){scanf("%I64d%I64d",&n,&m);map <int,int> mp;while(m--){scanf("%d",&op);if(op==1){scanf("%I64d%I64d%I64d",&l,&r,&p);if(l>r){tem=l;l=r;r=tem;}find(l-1,p);tem=sum;find(r,p);sum-=tem;map <int,int> ::iterator it;for(it=mp.begin();it!=mp.end();it++){tem=it->first;if(tem>=l&&tem<=r){if(gcd(p,it->first)==1)sum-=it->first;if(gcd(p,it->second)==1)sum+=it->second;}}printf("%I64d\n",sum);}else {scanf("%I64d%I64d",&l,&r);mp[l]=r;}}}return 0;}


 

//1010:一个模拟题,各种stl直接搞就好了,可是一个找共同的父亲节点让我们wa了半天,我们一直以为a如果是b的父亲,那么他们的公共父亲也是a,唉,后面看来讨论才知道,这里错了;傻逼了;

 

#include<iostream>#include<string.h>#include<set>#include <map >#include<algorithm>#include<vector>#include<string>using namespace std;struct node{int parent;string name;int cnt,dep;map < string,int > son;}num[50000];int cal(string s){int i,len=s.length();for(i=0;i<len;i++){if(s[i]!='.')return i;}}void f(int id,int dep){map <string,int> ::iterator it;num[id].dep=dep;for(it=num[id].son.begin();it!=num[id].son.end();it++){f(it->second,dep+1);}}void print(int id){int i;map <string,int> ::iterator it;for(i=1;i<num[id].dep;i++)cout<<".";cout<<num[id].name<<endl;for(it=num[id].son.begin();it!=num[id].son.end();it++)print(it->second);}int pa[50000];int main(){string a,b;char op[5];int n,m,i,len,id[2],k[2];while(1){cin>>n;if(!n)break;for(i=0;i<=n;i++){pa[i]=0;num[i].son.clear();num[i].parent=0;num[i].cnt=0;num[i].dep=0;}map <string ,int > mp;for(i=1;i<=n;i++){cin>>num[i].name;len=cal(num[i].name);a=num[i].name.substr(len,num[i].name.length()-len);mp[a]=i;num[i].name=a;if(len>0){num[pa[len-1]].cnt++;num[i].parent=pa[len-1];num[pa[len-1]].son[num[i].name]=i;}else num[i].parent=0;pa[len]=i;}cin>>m;f(1,1);while(m--){cin>>op;if(op[0]=='L')print(1);else if(op[0]=='b'){cin>>a;if(num[mp[a]].parent){cout<<num[num[mp[a]].parent].cnt<<endl;}else cout<<"1"<<endl;}else {cin>>a>>b;id[0]=mp[a];id[1]=mp[b];k[0]=id[0];k[1]=id[1];if(id[0]==id[1]){cout<<num[num[id[0]].parent].name<<endl;continue;}while(id[0]!=id[1]){if(num[id[0]].dep>num[id[1]].dep){id[0]=num[id[0]].parent;}else if(num[id[0]].dep<num[id[1]].dep)id[1]=num[id[1]].parent;else {id[0]=num[id[0]].parent;id[1]=num[id[1]].parent;}}if(id[0]==k[0])id[0]=num[k[0]].parent;else if(id[0]==k[1])id[0]=num[k[1]].parent;cout<<num[id[0]].name<<endl;}}}return 0;}