问题 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\n",Sum); 28 } 29 return 0; 30 }
问题 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 }
问题 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 }
问题 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\n",ans); 142 } 143 return 0; 144 }
http://files.cnblogs.com/files/SXia/solution.pdf