// //

同志们的毒害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 }
p酒桶

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

 

  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;

  

posted @ 2019-09-12 09:53  Zafkiel  阅读(155)  评论(1编辑  收藏  举报
Live2D //博客园自带,可加可不加