CSP-S模拟68 题解

Posted leom10

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSP-S模拟68 题解相关的知识,希望对你有一定的参考价值。

T1:

不难想到贪心,但是怎么贪,他有两个限制条件,所以不是很好搞,所以用一个类似与wqs二分的思路我可能在口胡,因为你肯定要把最小的给删掉,所以你限定一个x或y,然后在选出另一个限制,所以要同时维护删$k$个$x$最小和$y$最小,一个排序预处理,一个用堆维护即可。注意边界问题,思考实际意义。

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 const int N=1e5+10;
 5 int a[N];
 6 priority_queue<int> qx,qy;
 7 struct node{
 8     int x,y;
 9     bool friend operator < (node a,node b){
10         return a.x==b.x?(a.y<b.y):(a.x<b.x);
11     }
12 }p[N];
13 signed main(){
14     int T;
15     scanf("%lld",&T);
16     while(T--){
17         int n,m;
18         scanf("%lld%lld",&n,&m);
19         priority_queue<int,vector<int>,greater<int> >q;
20         for(int i=1;i<=n;++i){
21             scanf("%lld%lld",&p[i].x,&p[i].y);
22         }
23         sort(p+1,p+n+1);
24         for(int i=m+1;i<=n;++i) q.push(p[i].y);
25         int ans=p[m+1].x*q.top();
26         for(int i=m;i>=0;--i){
27             q.pop();q.push(p[i].y);
28             ans=max(ans,p[i].x*q.top());
29         }
30         printf("%lld
",ans);
31     }
32 }
d

T2:

考试时啥都没想到,连那个最小联通块都没分析出来是什么。通过手玩可以发现他所说的最小联通块就是所有点的LCA到每个节点的链,然后对于每一个询问值,只要查他的前趋后继即可,思路类似于平衡树那道题,宠物收养所,然后树上每条链其实就是树上的一段区间,用主席树维护即可,具体方法为查询问的值在区间的排名$rk$(准确来说是小于等于它的数的个数),然后前趋排名为$rk$,后继为$rk+1$,在查区间第k大即可,注意特判没有前趋或后继的情况。

特别注意在线不要只把值赋给LCA,$p[1]$也要改。

调了一下午 kuku

技术图片
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+10;
  4 struct Chairman_Tree{
  5     int l,r,size;
  6 }tr[N*40];
  7 int first[N],nex[N<<1],to[N<<1],tot,fr[N<<1];
  8 void add(int a,int b){
  9     to[++tot]=b,nex[tot]=first[a],first[a]=tot,fr[tot]=a;
 10 }
 11 int fa[N][22],d[N],root[N*40],p[N*3],a[N];
 12 void bfs(){
 13     queue<int> q;
 14     q.push(1);
 15     d[1]=1;
 16     while(q.size()){
 17         int x=q.front();q.pop();
 18         for(int i=first[x];i;i=nex[i]){
 19             int y=to[i];
 20             if(d[y]) continue;
 21             d[y]=d[x]+1;
 22             fa[y][0]=x;
 23             for(int j=1;j<=19;++j) fa[y][j]=fa[fa[y][j-1]][j-1];
 24             q.push(y);
 25         }
 26     }
 27 }
 28 int LCA(int x,int y){
 29     if(d[x]>d[y]) swap(x,y);
 30     for(int i=19;i>=0;--i) if(d[fa[y][i]]>=d[x]) y=fa[y][i];
 31     if(x==y) return x;
 32     for(int i=19;i>=0;--i) if(fa[y][i]!=fa[x][i]) y=fa[y][i],x=fa[x][i];
 33     return fa[x][0];
 34 }
 35 int cnt;
 36 void insert(int &x,int v,int l,int r,int pos){
 37     x=++cnt;
 38     tr[x]=tr[v];
 39     tr[x].size++;
 40     if(l==r) return ;
 41     int mid=(l+r)>>1;
 42     if(pos<=mid) insert(tr[x].l,tr[v].l,l,mid,pos);
 43     else insert(tr[x].r,tr[v].r,mid+1,r,pos);
 44 }
 45 int maxn=0;
 46 void dfs(int x){//cout<<"x=="<<x<<endl;
 47 //    cout<<x<<" "<<fa[x][0]<<" "<<a[x]<<endl;
 48     insert(root[x],root[fa[x][0]],1,maxn,a[x]);
 49     for(int i=first[x];i;i=nex[i]){
 50         int y=to[i];
 51         if(y==fa[x][0]) continue;
 52         dfs(y);
 53     }
 54 }
 55 int query(int u,int v,int l,int r,int val){
 56     if(r<=val) return tr[v].size-tr[u].size;
 57     int mid=(l+r)>>1;
 58     int als=tr[tr[v].l].size-tr[tr[u].l].size;
 59     if(val<=mid) return query(tr[u].l,tr[v].l,l,mid,val);
 60     else return als+query(tr[u].r,tr[v].r,mid+1,r,val);
 61 }
 62 int kth(int u,int v,int l,int r,int rk){
 63     if(l==r) return l;
 64     int mid=(l+r)>>1;
 65     int als=tr[tr[v].l].size-tr[tr[u].l].size;
 66     if(rk<=als) return kth(tr[u].l,tr[v].l,l,mid,rk);
 67     else return kth(tr[u].r,tr[v].r,mid+1,r,rk-als);
 68 }
 69 
 70 int find(int x,int fa,int val){
 71     int tmp=query(root[fa],root[x],1,maxn,val);
 72     int fr=tmp,aft=tmp+1;
 73 //    cout<<"tmp=="<<tmp<<endl;
 74     int frv=0x7fffffff,aftv=0x7fffffff;
 75 //    if(aft>d[x]-d[fa]) cout<<"HHH"<<endl;
 76     int res=0x7fffffff;
 77     if(fr>0) frv=kth(root[fa],root[x],1,maxn,fr),res=min(res,abs(frv-val));
 78     if(aft<=tr[root[x]].size-tr[root[fa]].size) aftv=kth(root[fa],root[x],1,maxn,aft),res=min(res,abs(aftv-val));
 79 //    cout<<"x=="<<x<<" fa=="<<fa<<" val=="<<val<<endl;
 80 //    cout<<"fr=="<<fr<<" aft=="<<aft<<endl;
 81 //    cout<<"frv=="<<frv<<" aftv=="<<aftv<<endl;
 82     return res;
 83 }
 84 
 85 int main(){
 86     int n,q,type;
 87     scanf("%d%d%d",&n,&q,&type);
 88     for(int i=1;i<=n;++i) {scanf("%d",&a[i]);maxn=max(maxn,a[i]);}
 89     for(int i=1;i<n;++i){
 90         int x,y;
 91         scanf("%d%d",&x,&y);
 92         add(x,y);
 93         add(y,x);
 94     }
 95     bfs();
 96 //    for(int i=1;i<=tot;++i) cout<<fr[i]<<" "<<to[i]<<endl;
 97     dfs(1);
 98     int lastans=0;
 99     for(int i=1;i<=q;++i){
100         int rvalue,k;
101         scanf("%d%d",&rvalue,&k);
102         scanf("%d",&p[1]);
103         int lca=p[1]=(p[1]-1+lastans*type)%n+1;
104         for(int j=2;j<=k;++j){
105             scanf("%d",&p[j]);
106             p[j]=(p[j]-1+lastans*type)%n+1;
107             lca=LCA(lca,p[j]);
108         }
109 //        cout<<"Lca=="<<lca<<endl;
110         int ans=0x7fffffff;
111         for(int j=1;j<=k;++j) ans=min(ans,find(p[j],fa[lca][0],rvalue));
112         lastans=ans;
113         printf("%d
",ans);
114     }
115 }
116 /*
117 3 1 0
118 18 99 59
119 1 2
120 2 3
121 15 3 2 2 3
122 */
e

 

T3:不会,鸽了

以上是关于CSP-S模拟68 题解的主要内容,如果未能解决你的问题,请参考以下文章

CSP-S模拟测试69 题解

[CSP-S模拟测试59]题解

冲刺CSP-S集训模拟赛总结

[CSP-S模拟测试53]题解

[CSP-S模拟测试74]题解

csp-s模拟测试61砖块, 数字,甜圈题解