20170508测试

问题 A: lyklyk?lyklyk!

时间限制: 1 Sec  内存限制: 256 MB

题目描述

Lyk得到了一个1~n的全排列。Txm每次会交换第i个数和第j个数,对于每次交换,lyk需要回答该全排列的逆序对数为多少。
“1、2、3、4......248289469!”lyk如是回答道。
“最后答案取模2......”

输入

第一行一个数,n
第二行为1~n的某个全排列
第三行一个数m,表示交换操作的次数。
接下来m行,每行两个数i和j

输出

M行,表示m次交换后的答案。

样例输入

4 1 2 3 4 1 1 2

样例输出

1

提示

Constraints 

对于30%,n,m<=1000

对于100%,n,m<=100000

这题考试时i==j没判,怒送出题人(张浩威狗头张)100分。

题解在最后,,

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int T[100005];
 6 void add(int x){
 7     for (int i=x;i<=100000;i+=(i&(-i))) T[i]+=1;
 8 }
 9 int sum(int x){
10     int Sum=0;
11     for (int i=x;i>0;i-=(i&(-i))) Sum+=T[i];
12     return Sum;
13 }
14 int main(){
15     //freopen("lyk.in","r",stdin);
16     //freopen("lyk.out","w",stdout);
17     int    n,Sum=0; scanf("%d",&n);
18     for (int i=1;i<=n;i++){
19         int a; scanf("%d",&a);
20         add(a); Sum=(i-sum(a)+Sum)%2;
21     }
22     int m; scanf("%d",&m);
23     for (int i=1;i<=m;i++){
24         int x,y; scanf("%d%d",&x,&y);
25         if (x!=y) 
26         Sum++,Sum%=2;
27         printf("%d
",Sum);
28     }
29     return 0;
30 }
View Code

问题 B: tower

时间限制: 1 Sec  内存限制: 256 MB

题目描述

Lyk去推塔。但是推第n座塔必须先推了第1~n-1座塔。
为了加快速度lyk召唤出了szh和txm。求lyk和他的召唤兽们为了推完所有塔所经过的最短距离。

输入

第一行一个数N,代表一共要去多少个城市。
下面N-1 行,对于第 i 行,有 n-i 个数,表示第 i 个城市分别和第i+1, i+2, i+3, ……, N 的距离(距离<=10000)

输出

一个数,表示最短距离

样例输入

5 1 1 1 2 33 33 33 33 33 33

样例输出

36

提示

Constraints 

对于30%,n<=10

对于100%,n<=100

 TM最短路又忘打了→→。

题解在最后,,

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 long long f[105][105][105],a[105][105];
 6 long long min_(long long a,long long b){
 7     return a>b?b:a;
 8 }
 9 int main(){
10     //freopen("tower.in","r",stdin);
11     //freopen("tower.out","w",stdout);
12     int n; scanf("%d",&n);
13     for (int i=1;i<=n;i++)
14         for (int j=1;j<=n;j++) a[i][j]=(long long)1e+10;
15     for (int i=1;i<=n;i++)
16         for (int j=i+1;j<=n;j++) scanf("%lld",&a[i][j]);
17     for (int k=1;k<=n;k++)
18         for (int i=1;i<=n;i++)
19             for (int j=1;j<=n;j++)
20                 if (a[i][k]+a[k][j]<a[i][j]) a[i][j]=a[i][k]+a[k][j];
21     for (int i=1;i<=n;i++)
22         for (int j=1;j<=n;j++) 
23             for (int z=1;z<=n;z++) f[i][j][z]=(long long)1e+13;
24     f[1][1][1]=0;
25     for (int i=1;i<=n;i++)
26         for (int j=1;j<=n;j++)
27             for (int z=1;z<=n;z++){
28                 int t=max(i,j); t=max(t,z);
29                 f[t+1][j][z]=min(f[t+1][j][z],f[i][j][z]+a[i][t+1]);
30                 f[i][t+1][z]=min(f[i][t+1][z],f[i][j][z]+a[j][t+1]);
31                 f[i][j][t+1]=min(f[i][j][t+1],f[i][j][z]+a[z][t+1]);
32             }
33     long long Min=1e+15;
34     for (int i=1;i<=n;i++)
35         for (int j=1;j<=n;j++)
36         Min=min_(Min,f[n][i][j]),Min=min_(Min,f[i][n][j]),Min=min_(Min,f[i][j][n]);
37     printf("%lld",Min);
38     return 0;
39 }
View Code

问题 C: pinball

时间限制: 1 Sec  内存限制: 256 MB

题目描述

小天才lyk喜欢玩一个叫pinball的游戏。游戏规则如下:
Pinball的游戏界面由m+2行、n列组成。第一行在顶端。一个球会从第一行出发,开始垂直下落,lyk会得到一个积分当他击中一个球的时候。
小天才lyk觉得这太困难了,于是在界面中放入了一些漏斗,一共有m个漏斗分别放在第2~m+1行,第i个漏斗的作用是把经过第i+1行且列数在Ai~Bi之间的球将其移到第Ci列。
但是使用每个漏斗都是需要付钱的,第i个漏斗需要支付Di的价钱,lyk需要保留一些漏斗,使得球无论从第一行的哪一列开始放,都只可能到达第m+2行的唯一一列。同时,lyk希望花费最小的价钱。

输入

第一行两个数,m和n
接下来m行,第i+1行描述第i个漏斗的属性,Ai,Bi,Ci,Di(1<=Ai<=Ci<=Bi<=n,1<=Di<=1000000000)。

输出

若不存在一种方案能满足条件则输出-1,否则输出最小话费。

样例输入

5 6 2 4 3 5 1 2 2 8 3 6 5 2 4 6 4 7 2 4 3 10 3 5 2 4 3 10 1 3 1 20 2 5 4 30

样例输出

25 -1

提示

【样例解释1】



如图,只需使用第2、4、5个漏斗即可。


【数据范围】

对于20%的数据,m<=10,n<=1000

对于 40%的数据,m<=200

对于60%的数据,m<=1000

对于100%的数据,m<=100000,2<=n<=1000000000

题解在最后,,

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 using namespace std;
 8 #define ll long long
 9 const ll INF=(ll)1<<60;
10 #define N 110000
11 int n,m,a[N],b[N],c[N],d[N],q[N];
12 ll ans=INF;
13 struct seg{
14     ll Min[N*4],a[N];
15     void build(int u,int l,int r){
16         if(l==r){
17             Min[u]=a[l];
18             return;
19         }
20         int mid=(l+r)>>1;
21         build(u*2,l,mid);
22         build(u*2+1,mid+1,r);
23         Min[u]=min(Min[u*2],Min[u*2+1]);
24     }
25     ll find(int u,int l,int r,int x,int y){
26         if(x<=l && y>=r)return Min[u];
27         if(x>r || y<l)return INF;
28         int mid=(l+r)>>1;
29         return min(find(u*2,l,mid,x,y),find(u*2+1,mid+1,r,x,y));
30     }
31     void change(int u,int l,int r,int x,ll w){
32         if(l==r){
33             Min[u]=min(w,Min[u]);
34             return;
35         }
36         int mid=(l+r)>>1;
37         if(x<=mid)change(u*2,l,mid,x,w);
38         else change(u*2+1,mid+1,r,x,w);
39         Min[u]=min(Min[u*2],Min[u*2+1]);
40     }
41 }t1,t2;
42 int bin1(int k){
43     int l=1,r=q[0];
44     while(l<r){
45         int mid=(l+r)/2;
46         if(q[mid]>=k)r=mid;
47         else l=mid+1;
48     }
49     return l;
50 }
51 int bin2(int k){
52     int l=1,r=q[0];
53     while(l<r){
54         int mid=(l+r)/2+1;
55         if(k>=q[mid])l=mid;
56         else r=mid-1;
57     }
58     return l;
59 }
60 int main(){
61     freopen("pinball.in","r",stdin);
62     freopen("pinball.out","w",stdout);
63     scanf("%d%d",&n,&m);
64     q[++q[0]]=1;
65     q[++q[0]]=m;
66     for(int i=1;i<=n;i++)scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]),q[++q[0]]=c[i];
67     sort(q+1,q+q[0]+1);
68     q[0]=1;
69     for(int i=2;i<=n+2;i++)
70         if(q[i]!=q[q[0]])q[++q[0]]=q[i];
71     m=q[0];
72     for(int i=1;i<=q[0];i++){
73         t1.a[i]=INF*(int)(i>1);
74         t2.a[i]=INF*(int)(i<q[0]);
75     }
76     t1.build(1,1,q[0]);
77     t2.build(1,1,q[0]);
78     for(int i=1;i<=n;i++){
79         a[i]=bin1(a[i]);
80         b[i]=bin2(b[i]);
81         c[i]=bin1(c[i]);
82         ll f1=t1.find(1,1,q[0],a[i],b[i]),f2=t2.find(1,1,q[0],a[i],b[i]);
83         ans=min(f1+f2+d[i],ans);
84         t1.change(1,1,q[0],c[i],f1+d[i]);
85         t2.change(1,1,q[0],c[i],f2+d[i]);
86     }
87     if(ans<INF)cout<<ans<<endl;
88     else cout<<-1<<endl;
89     return 0;
90 }
View Code

问题 D: tree

时间限制: 3 Sec  内存限制: 512 MB

题目描述

小天才lyk打游戏又被zyh抓啦!
学校的教室呈树状,即n个点由n-1条边连接。据可靠情报lyk正藏在编号为a~b的教室中,而zyh正在编号为c~d的教室中寻找,保证a~b和c~d没有交集(不然lyk就要被抓啦)。
作为lyk同盟的你当然希望lyk能逃脱啦,所以你希望知道lyk和zyh相距最远可能多少。
即你需要求出max{dis(i,j) |a<=i<=b,c<=j<=d}

输入

第一行一个数,n。
第二行到第n行每行三个数描述路的情况,x,y,z(1<=x,y<=n,1<=z<=10000)表示x和y之间有一条长度为z的路。
第n+1行一个数m,表示询问次数。
接下来m行,每行四个数a,b,c,d。

输出

输出lyk和zyh可能的最远距离。

样例输入

5 1 2 1 2 3 2 1 4 3 4 5 4 1 2 3 4 5

样例输出

10

提示

【数据范围】

对于10%的数据,n,m<=50

对于30%的数据,n,m<=500

对于60%的数据,n,m<=3000

对于100%的数据,n,m<=100000

题解在最后,,

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef long double ld;
  5 typedef pair<int,int> pr;
  6 #define rep(i,a,n) for(int i=a;i<=n;i++)
  7 #define per(i,n,a) for(int i=n;i>=a;i--)
  8 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
  9 #define clr(a) memset(a,0,sizeof a)
 10 #define pb push_back
 11 #define mp make_pair
 12 #define fi first
 13 #define sc second
 14 ll pp=1000000007;
 15 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
 16 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
 17 ll read(){
 18     ll ans=0;
 19     char last=' ',ch=getchar();
 20     while(ch<'0' || ch>'9')last=ch,ch=getchar();
 21     while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
 22     if(last=='-')ans=-ans;
 23     return ans;
 24 }
 25 //head
 26 #define N 110000
 27 int v[N*2],Next[N*2],head[N],cost[N*2],Q[N*2],q[N*2],b[N*4][3],num=0,n,m;
 28 int pre[N*2][20],B[N*2],lab[N],fa[N],dep[N];
 29 void add(int x,int y,int z){
 30     v[++num]=y;Next[num]=head[x];head[x]=num;cost[num]=z;
 31 }
 32 void bfs(){
 33     int top=1;
 34     q[1]=1;
 35     while(top){
 36         int u=q[top];
 37         Q[++Q[0]]=u;
 38         lab[u]=Q[0];
 39         if(head[u] && v[head[u]]==fa[u])head[u]=Next[head[u]];
 40         if(head[u]){
 41             dep[v[head[u]]]=dep[u]+cost[head[u]];
 42             fa[v[head[u]]]=u;
 43             q[++top]=v[head[u]];
 44             head[u]=Next[head[u]];
 45             }
 46         else --top;
 47     }
 48     rep(i,1,Q[0]){
 49         pre[i][0]=Q[i];
 50         for(int j=1;(1<<j)<=i;++j)
 51             if(dep[pre[i][j-1]]<dep[pre[i-(1<<(j-1))][j-1]])pre[i][j]=pre[i][j-1];
 52             else pre[i][j]=pre[i-(1<<(j-1))][j-1];
 53     }
 54     for(int j=0;(1<<j)<=Q[0];j++)B[1<<j]=j;
 55     rep(j,2,Q[0])
 56         if(!B[j])B[j]=B[j-1];
 57 }
 58 int calc(int x,int y){
 59     int tt=dep[x]+dep[y];
 60     x=lab[x],y=lab[y];
 61     if(x>y)swap(x,y);
 62     int z=B[y-x+1];
 63     int t1=pre[y][z],t2=pre[x+(1<<z)-1][z];
 64     if(dep[t1]<dep[t2])return tt-dep[t1]-dep[t1];
 65     else return tt-dep[t2]-dep[t2];
 66 }
 67 void build(int u,int l,int r){
 68     if(l==r){
 69         b[u][0]=1;
 70         b[u][1]=l;
 71         return ;
 72     }
 73     int mid=(l+r)>>1;
 74     build(u<<1,l,mid);
 75     build(u<<1|1,mid+1,r);
 76     q[0]=0;
 77     rep(i,1,b[u<<1][0])q[++q[0]]=b[u<<1][i];
 78     rep(i,1,b[u<<1|1][0])q[++q[0]]=b[u<<1|1][i];
 79     b[u][0]=2;
 80     b[u][1]=q[1];
 81     b[u][2]=q[2];
 82     int Max=calc(q[1],q[2]);
 83     rep(i,3,q[0])
 84         rep(j,1,i-1){
 85             int t=calc(q[i],q[j]);
 86             if(t>Max){
 87                 Max=t;
 88                 b[u][1]=q[i];
 89                 b[u][2]=q[j];
 90             }
 91         }
 92 }
 93 void get(int u,int l,int r,int x,int y){
 94     if(x>r || y<l)return ;
 95     if(x<=l && y>=r){
 96         rep(i,1,b[u][0])q[++q[0]]=b[u][i];
 97         if(q[0]==1)return;
 98         int Max=0,ans1,ans2;
 99         rep(i,2,q[0])
100           rep(j,1,i-1){
101             int t=calc(q[i],q[j]);
102             if(t>Max){
103                 Max=t;
104                 ans1=q[i];
105                 ans2=q[j];
106             }
107         }
108         q[0]=2;
109         q[1]=ans1;
110         q[2]=ans2;
111         return;
112     }
113     int mid=(l+r)>>1;
114     get(u<<1,l,mid,x,y);
115     get(u<<1|1,mid+1,r,x,y);
116 }
117 int main(){
118     freopen("tree.in","r",stdin);
119     freopen("tree.out","w",stdout);
120     n=read();
121     rep(i,1,n-1){
122         int x=read(),y=read(),z=read();
123         add(x,y,z);
124         add(y,x,z);
125     }
126     bfs();
127     build(1,1,n);
128     m=read();
129     while(m--){
130         int l=read(),r=read();
131         q[0]=0;
132         get(1,1,n,l,r);
133         int t1=q[1],t2=q[2];
134         l=read(),r=read();
135         q[0]=0;
136         get(1,1,n,l,r);
137         int ans=calc(q[1],t1);
138         ans=max(ans,calc(q[1],t2));
139         ans=max(ans,calc(q[2],t1));
140         ans=max(ans,calc(q[2],t2));
141         printf("%d
",ans);
142     }
143     return 0;
144 }
View Code

http://files.cnblogs.com/files/SXia/solution.pdf

原文地址:https://www.cnblogs.com/SXia/p/6863750.html