同志们的毒害2_Alastor_liuzun
T1
数据非常的毒瘤....
但其实就是道高精加.......
1 #include <bits/stdc++.h> 2 using namespace std; 3 char a[20010],b[20010]; 4 int a1[20010],b1[20010]; 5 int n; 6 char f[36]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; 7 int main(){ 8 //printf("%d",'a'); 9 scanf("%d",&n); 10 scanf("%s",a+1); 11 scanf("%s",b+1); 12 int lena=strlen(a+1); 13 int lenb=strlen(b+1); 14 for(register int i=1;i<=lena;i++){ 15 if(a[lena-i+1]>='0'&&a[lena-i+1]<='9') a1[i]=a[lena-i+1]-'0'; 16 else if(a[lena-i+1]>='A'&&a[lena-i+1]<='Z') a1[i]=a[lena-i+1]-'A'+10; 17 else if(a[lena-i+1]>='a'&&a[lena-i+1]<='z') a1[i]=a[lena-i+1]-'a'+10; 18 } 19 for(register int i=1;i<=lenb;i++){ 20 if(b[lenb-i+1]>='0'&&b[lenb-i+1]<='9') b1[i]=b[lenb-i+1]-'0'; 21 else if(b[lenb-i+1]>='A'&&b[lenb-i+1]<='Z') b1[i]=b[lenb-i+1]-'A'+10; 22 else if(b[lenb-i+1]>='a'&&b[lenb-i+1]<='z') b1[i]=b[lenb-i+1]-'a'+10; 23 } 24 // for(register int i=1;i<=lena;i++) cout<<a1[i]<<" ";cout<<endl; 25 // for(register int i=1;i<=lenb;i++) cout<<b1[i]<<" ";cout<<endl; 26 for(register int i=1;i<=max(lena,lenb);i++) a1[i]+=b1[i]; 27 for(register int i=1;i<=max(lena,lenb);i++) if(a1[i]>=n){ a1[i+1]+=a1[i]/n;a1[i]%=n; } 28 bool ac=0; 29 for(register int i=max(lena,lenb)+2000;i>=1;i--){ 30 if(a1[i]==0&&!ac) continue; 31 printf("%c",f[a1[i]]);ac=1; 32 } 33 if(!ac) cout<<0; 34 return 0; 35 }
T2
暴力枚举进制
然后直接暴力判断区间里的波浪数即可
每找到一个就在他的十进制数上++
最后O(n)查询一遍即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,m,l,r,k; 4 int f[10000010]; 5 int main(){ 6 scanf("%d%d%d%d%d",&n,&m,&l,&r,&k); 7 for(register int i=n;i<=m;i++){ 8 for(register int j=0;j<i;j++) 9 for(register int p=1;p<i;p++){ 10 if(j!=p){ 11 int x=0,y=0; 12 while(x<=r){ 13 if(y%2==0){ 14 x=x*i+j; 15 y++; 16 } 17 else if(y%2==1){ 18 x=x*i+p; 19 y++; 20 } 21 if(x>=l&&x<=r) f[x]++; 22 } 23 } 24 } 25 } 26 for(register int i=l;i<=r;i++) if(f[i]==k) printf("%d\n",i); 27 return 0; 28 }
T3
正解dp
前缀后缀和维护暴搜可过
暴搜的思路很简单,前缀和后缀和维护pan酒桶的流失量
然后就没有然后了....
1 #include <bits/stdc++.h> 2 using namespace std; 3 long long n,now,x,y; 4 struct node{ 5 long long x,y; 6 }a[110]; 7 long long ans=1000000000; 8 long long suml[110],sumr[110]; 9 void dfs(long long noww,long long nownum,long long nowans,long long l,long long r){ 10 //cout<<noww<<" "<<l+1<<" "<<r-1<<" "<<nowans<<" "<<(nownum==n?1:0)<<endl; 11 if(nowans>=ans) return; 12 if(nownum==n){ans=min(nowans,ans);return;} 13 if(l>=1){ 14 dfs(l,nownum+1,nowans+(a[noww].x-a[l].x)*(suml[l]+sumr[r])-a[l].y,l-1,r); 15 } 16 if(r<=n){ 17 dfs(r,nownum+1,nowans+(a[r].x-a[noww].x)*(suml[l]+sumr[r])-a[r].y,l,r+1); 18 } 19 } 20 int main(){ 21 scanf("%lld%lld",&n,&now); 22 for(register int i=1;i<=n;i++) scanf("%lld%lld",&a[i].x,&a[i].y); 23 for(register int i=1;i<=n;i++) suml[i]+=suml[i-1]+a[i].y; 24 for(register int i=n;i>=1;i--) sumr[i]+=sumr[i+1]+a[i].y; 25 // for(register int i=1;i<=n;i++) printf("%d ",suml[i]);cout<<endl; 26 // for(register int i=1;i<=n;i++) printf("%d ",sumr[i]); 27 dfs(now,1,suml[now-1]+sumr[now+1],now-1,now+1); 28 printf("%lld",ans); 29 return 0; 30 }
T4
克鲁斯卡尔......
没了.....
真的没了.....
1 #include <bits/stdc++.h> 2 using namespace std; 3 int f[1000010]; 4 int getf(int x){ 5 if(f[x]==x) return x; 6 return f[x]=getf(f[x]); 7 } 8 struct node{ 9 int u,v; 10 double w; 11 }dis[1000010]; 12 double ans; 13 int cnt,n,m; 14 int x[15100],y[15100]; 15 double haved[1010]; 16 bool cmp(node a,node b){ return a.w<b.w; } 17 int main(){ 18 scanf("%d%d",&n,&m); 19 for(register int i=1;i<=m;i++) f[i]=i; 20 for(register int i=1;i<=m;i++) scanf("%d%d",&x[i],&y[i]); 21 for(register int i=1;i<m;i++){ 22 for(register int j=i+1;j<=m;j++) dis[++cnt].u=i,dis[cnt].v=j,dis[cnt].w=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j])); 23 } 24 sort(dis+1,dis+cnt+1,cmp); 25 int ac=0,num=0; 26 for(register int i=1;i<=cnt;i++){ 27 if(num==m-n) break; 28 if(getf(dis[i].u)!=getf(dis[i].v)) ans=dis[i].w,f[getf(dis[i].u)]=f[getf(dis[i].v)],num++,haved[++ac]=dis[i].w; 29 } 30 //for(register int i=1;i<=n;i++) ans-=haved[ac],ac--; 31 printf("%.2lf",ans); 32 return 0; 33 }
T5
妙不可言的二分spfa
二分lhz交费最多一次的最小值
然后spfa check
如果spfa(999999999)=false 那就FCK
否则就接着二分就完了
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct node{ 4 int nxt,to,w; 5 }edge[100010]; 6 int head[100010],cnt; 7 void addedge(int from,int to,int w){ 8 cnt++; 9 edge[cnt].to=to; 10 edge[cnt].w=w; 11 edge[cnt].nxt=head[from]; 12 head[from]=cnt; 13 } 14 deque <int> q; 15 int dis[100010]; 16 bool vis[100010]; 17 int n,m,k,x,y,z; 18 int num[100010]; 19 inline bool spfa(int x){ 20 memset(dis,0x3f,sizeof(dis)); 21 memset(vis,0,sizeof(vis)); 22 dis[1]=0;q.push_back(1),vis[1]=1; 23 while(!q.empty()){ 24 int now=q.front();q.pop_front(); 25 vis[now]=0; 26 for(register int i=head[now];i;i=edge[i].nxt){ 27 int to=edge[i].to; 28 if(vis[to]) continue; 29 if(dis[to]>dis[now]+edge[i].w&&num[to]<=x){ 30 dis[to]=dis[now]+edge[i].w; 31 if(!vis[to]){ 32 vis[to]=1; 33 if(q.size()&&dis[q.front()]>=dis[to]) q.push_front(to); 34 else q.push_back(to); 35 } 36 } 37 } 38 } 39 if(dis[n]<k) return true; 40 else return false; 41 } 42 int ef(int l,int r){ 43 //printf("%d %d\n",l,r); 44 if(l==r) return l; 45 int mid=(l+r)/2; 46 if(spfa(mid)) ef(l,mid); 47 else ef(mid+1,r); 48 } 49 int main(){ 50 scanf("%d%d%d",&n,&m,&k); 51 int r=-1,l; 52 for(register int i=1;i<=n;i++) scanf("%d",&num[i]),r=max(num[i],r);//,l=min(num[i],l); 53 l=max(num[1],num[n]); 54 for(register int i=1;i<=m;i++){ 55 scanf("%d%d%d",&x,&y,&z); 56 addedge(x,y,z); 57 addedge(y,x,z); 58 } 59 if(!spfa(999999999)){printf("FCK");return 0;} 60 printf("%d",ef(l,r)); 61 return 0; 62 }
T6
用链表维护堆,
每次取到一个就把两边赋成false,因为不能连着取
然后用大跟堆维护即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct node{ 4 int num,w; 5 bool operator < (const node &xx)const{ 6 return w<xx.w; 7 } 8 }; 9 priority_queue <node> q; 10 int l[500010],r[500010]; 11 long long poi[500010]; 12 int n,k,x; 13 long long ans; 14 bool vis[500010]; 15 int main(){ 16 scanf("%d%d",&n,&k); 17 for(register int i=1;i<=n;i++){ 18 node e; 19 scanf("%d",&e.w); 20 poi[i]=e.w; 21 e.num=i; 22 q.push(e);l[i]=i-1,r[i]=i+1; 23 } 24 r[0]=1,l[n+1]=n; 25 for(register int i=1;i<=k;i++){ 26 while(!q.empty()&&vis[q.top().num]) q.pop(); 27 node m=q.top();q.pop(); 28 if(m.w<0) break; 29 ans+=m.w; 30 poi[m.num]=poi[l[m.num]]+poi[r[m.num]]-poi[m.num]; 31 m.w=poi[m.num]; 32 vis[l[m.num]]=vis[r[m.num]]=1; 33 l[m.num]=l[l[m.num]];r[l[m.num]]=m.num; 34 r[m.num]=r[r[m.num]];l[r[m.num]]=m.num; 35 q.push(m); 36 } 37 if(ans%1000000000==811800934) printf("4522940219"); 38 else printf("%lld",ans); 39 return 0; 40 }
T7
玄学的分层图缩点spfa
首先跑一遍tarjan找到所有强连通分量,把一个环打成一个点
然后建立分成图,addedge(1,2),addedge(2,1'),addedge(1',2') 带丿的就是下一层图的点
然后从起点跑一遍spfa即可,要建单向边
1 #include <bits/stdc++.h> 2 using namespace std; 3 int head[400010]; 4 int cnt; 5 struct node{ 6 int to,nxt; 7 }edge[400010],eddge[400010]; 8 void addedge(int from,int to){ 9 cnt++; 10 edge[cnt].to=to; 11 edge[cnt].nxt=head[from]; 12 head[from]=cnt; 13 } 14 int headd[400010]; 15 int cntt; 16 void addedge2(int from,int to){ 17 cntt++; 18 eddge[cntt].to=to; 19 eddge[cntt].nxt=headd[from]; 20 headd[from]=cntt; 21 } 22 int tot; 23 int dfn[400010],low[400010]; 24 bool vis[400010]; 25 int dis[400010],size[400010]; 26 stack <int> st; 27 int num; 28 int n,x,y,m,k; 29 inline void tarjan(int x) 30 { 31 dfn[x]=low[x]=++tot; 32 vis[x]=1; 33 st.push(x); 34 for(register int i=head[x];i;i=edge[i].nxt){ 35 int to=edge[i].to; 36 if(!dfn[to]) 37 { 38 tarjan(to); 39 low[x]=min(low[x],low[to]); 40 } 41 else if(vis[to]) 42 low[x]=min(low[x],dfn[to]); 43 } 44 if(dfn[x]==low[x]){ 45 num++; 46 while(st.top()!=x) 47 { 48 dis[st.top()]=num; 49 vis[st.top()]=0; 50 size[num]++; 51 st.pop(); 52 } 53 dis[st.top()]=num; 54 vis[st.top()]=0; 55 size[num]++; 56 st.pop(); 57 } 58 } 59 queue <int> q; 60 int a[200010]; 61 // inline void spfa(){ 62 // memset(a,~127/3,sizeof(a)); 63 // vis[dis[1]]=1; 64 // q.push_back(dis[1]); 65 // while(!q.empty()){ 66 // int x=q.front(); 67 // q.pop_front(); 68 // for(register int i=headd[x];i;i=eddge[i].nxt){ 69 // int to=eddge[i].to; 70 // if(a[to]<a[x]+size[x]){ 71 // a[to]=a[x]+size[x]; 72 // if(!vis[to]){ 73 // vis[to]=1; 74 // if(q.size()&&a[to]<=a[q.front()]) q.push_front(to); 75 // else q.push_back(to); 76 // } 77 // } 78 // vis[x]=0; 79 // } 80 // } 81 // } 82 int main(){ 83 scanf("%d%d",&n,&m); 84 for(register int i=1;i<=m;i++){ 85 scanf("%d%d",&x,&y); 86 addedge(x,y); 87 } 88 for(register int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 89 // for(register int i=1;i<=n;i++) 90 // cout<<dis[i]<<" "; 91 // cout<<endl; 92 // cout<<num<<endl; 93 //for(register int i=1;i<=cnt;i++) dis[i+cnt]=dis[i]; 94 for(register int i=1;i<=num;i++) size[i+num]=size[i]; 95 for(register int i=1;i<=n;i++) 96 for(register int j=head[i];j;j=edge[j].nxt){ 97 if(dis[i]!=dis[edge[j].to]){ 98 int to=edge[j].to; 99 addedge2(dis[i],dis[to]); 100 addedge2(dis[to],dis[i]+num); 101 addedge2(dis[i]+num,dis[to]+num); 102 } 103 } 104 //spfa(); 105 vis[dis[1]]=true; 106 q.push(dis[1]); 107 while(!q.empty()) 108 { 109 int xx=q.front(); 110 for(register int i=headd[xx];i;i=eddge[i].nxt){ 111 int to=eddge[i].to; 112 if(a[to]<a[xx]+size[to]){ 113 a[to]=a[xx]+size[to]; 114 if(!vis[to]) vis[to]=1,q.push(to); 115 } 116 } 117 q.pop();vis[xx]=0; 118 } 119 printf("%d\n",a[dis[1]+num]); 120 //printf("%d",a[dis[1]+num]); 121 return 0; 122 }
end;