csps-s模拟测试62,63Graph,Permutation,Tree,Game题解
題面:https://www.cnblogs.com/Juve/articles/11631298.html
permutation:
參考:https://www.cnblogs.com/clno1/p/10832579.html
因?yàn)樵瓉淼臄?shù)組不好做于是我們想反過來數(shù)組,根據(jù)交換條件:值相鄰且位置差大于等于k,那么在變換后的數(shù)組就變成了位置相鄰且差值大于等于k。這樣的話變換操作變成了,相鄰的大于等于k的值臨近交換,于是我們注意到因?yàn)楝F(xiàn)在只能臨近交換的原因,兩個(gè)差值小于k的數(shù)他們的相對位置不可能發(fā)生改變。那么問題就變成了,在只有一些相對位置限制條件下,無限制的可以隨意交換位置,求這個(gè)數(shù)組的最小字典序(原數(shù)組字典序最小也是現(xiàn)在數(shù)組字典序最小)。那么我們?nèi)菀紫氲酵負(fù)渑判颉?/p>
但是如果每個(gè)點(diǎn)都想后面差值小于k的點(diǎn)連邊的話,這個(gè)圖會變得十分巨大,時(shí)間無法承受。于是我們必循得考慮優(yōu)化建圖:我們注意到像a->b,b->c,a->c這種建圖,a->c這條邊是不必要的。于是我們想辦法避免掉這種無意義的邊,所以對于某個(gè)點(diǎn),我們讓它向后面的所有限制(即差值小于k)中只向最小的那一個(gè)點(diǎn)連邊,那么用線段樹維護(hù)這樣的信息,這樣就達(dá)到優(yōu)化建圖的目的。
這樣只向最小的連邊為什么是對的呢?借用上面大佬的一句話:倒著加入,顯然p_i 連向 (p_i-k, p_i)∪(p_i, p_i+k)。我們只需要分別連向兩個(gè)區(qū)間中下標(biāo)最小的那一個(gè)即可。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<vector>
6 #include<queue>
7 using namespace std;
8 const int MAXN=5e5+5;
9 int n,k,a[MAXN],pos[MAXN],du[MAXN],ans[MAXN],num=0;
10 vector<int>m[MAXN];
11 priority_queue<int>q;
12 int tr[MAXN<<2];
13 void update(int k,int l,int r,int opt,int val){
14 if(l==r){
15 tr[k]=min(tr[k],val);
16 return ;
17 }
18 int mid=(l+r)>>1;
19 if(opt<=mid) update(k<<1,l,mid,opt,val);
20 else update(k<<1|1,mid+1,r,opt,val);
21 tr[k]=min(tr[k<<1],tr[k<<1|1]);
22 }
23 int query(int k,int l,int r,int opl,int opr){
24 if(opl>opr) return 0x3f3f3f3f;
25 if(opl<=l&&r<=opr) return tr[k];
26 int mid=(l+r)>>1,res=0x3f3f3f3f;
27 if(opl<=mid) res=min(res,query(k<<1,l,mid,opl,opr));
28 if(opr>mid) res=min(res,query(k<<1|1,mid+1,r,opl,opr));
29 return res;
30 }
31 int main(){
32 scanf("%d%d",&n,&k);
33 for(int i=1;i<=n;++i){
34 scanf("%d",&a[i]);
35 pos[a[i]]=i;
36 }
37 memset(tr,0x3f,sizeof(tr));
38 for(int i=n;i>=1;--i){
39 int p=query(1,1,n,max(1,pos[i]-k+1),pos[i]);
40 if(p<=n) m[pos[i]].push_back(pos[p]),++du[pos[p]];
41 p=query(1,1,n,pos[i],min(n,pos[i]+k-1));
42 if(p<=n) m[pos[i]].push_back(pos[p]),++du[pos[p]];
43 update(1,1,n,pos[i],i);
44 }
45 for(int i=1;i<=n;++i){
46 if(!du[i]) q.push(-i);
47 }
48 while(!q.empty()){
49 int x=-q.top();
50 q.pop();
51 ans[x]=++num;
52 int N=m[x].size();
53 for(int i=0;i<N;++i){
54 int y=m[x][i];
55 --du[y];
56 if(!du[y]) q.push(-y);
57 }
58 }
59 for(int i=1;i<=n;++i){
60 printf("%d
",ans[i]);
61 }
62 return 0;
63 }
View Code
tree:
好像是個(gè)結(jié)論:邊權(quán)之和就是答案
#include<cstdio>
#define int long long
int n,ans=0;
signed main(){
scanf("%lld",&n);
for(int i=1,u,v,w;i<n;++i){
scanf("%lld%lld%lld",&u,&v,&w);
ans+=w;
}
printf("%lld
",ans);
return 0;
}
View Code
game:
模擬用堆可以有50分
考慮如何優(yōu)化
我們對于前p個(gè)數(shù)找出最大值,并開桶統(tǒng)計(jì)所有數(shù)出現(xiàn)的次數(shù)
然后對于一個(gè)新加入的點(diǎn),如果它大于當(dāng)前的最大值,那么下一個(gè)人一定選擇新加如的這個(gè)點(diǎn),所以最大值沒有變
否則更新新加入的數(shù)的次數(shù)并更新最大值
考慮到最大值一定不上升,所以復(fù)雜度較有保障
但是還是會T,所以我們離散化一下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define re register
using namespace std;
const int MAXN=100005;
int n,k,a[MAXN],p,tim[MAXN],cnt,b[MAXN];
signed main(){
scanf("%d%d",&n,&k);
for(re int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+n+1);
cnt=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
while(k--){
scanf("%d",&p);
re long long ans1=0,ans2=0;
re int maxp=0;
for(re int i=1;i<=p;++i){
++tim[a[i]];
maxp=max(maxp,a[i]);
}
ans1+=b[maxp];
--tim[maxp];
while(maxp>0&&tim[maxp]==0) --maxp;
for(re int i=2;i<=n;++i){
if(i&1){
if(p+1<=n){
++p;
if(a[p]>=maxp) ans1+=b[a[p]];
else{
ans1+=b[maxp];
--tim[maxp];
++tim[a[p]];
while(maxp>0&&tim[maxp]==0) --maxp;
}
}else{
ans1+=b[maxp];
--tim[maxp];
while(maxp>0&&tim[maxp]==0) --maxp;
}
}else{
if(p+1<=n){
++p;
if(a[p]>=maxp) ans2+=b[a[p]];
else{
ans2+=b[maxp];
--tim[maxp];
++tim[a[p]];
while(maxp>0&&tim[maxp]==0) --maxp;
}
}else{
ans2+=b[maxp];
--tim[maxp];
while(maxp>0&&tim[maxp]==0) --maxp;
}
}
}
printf("%lld
",ans1-ans2);
}
return 0;
}
View Code
總結(jié)
以上是生活随笔為你收集整理的csps-s模拟测试62,63Graph,Permutation,Tree,Game题解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDC 报告称 76% 的企业 IT 决
- 下一篇: dex2jar 和 jd-gui 的安装