• 「一本通 4.4 例 3」异象石 与 [SDOI2015]寻宝游戏


    这两个题差不多先说异象石把

    主要是找到本题规律,将所加入的点按dfs序排序,记录为a[1],a[2]..a[n]则当前的答案为每个点与前一个点的距离(第一个点则与最后一点)

    当然要动态维护答案,每加入一个点就+与前驱的距离+与后驱的距离-前驱与后驱的距离(删点的话ans减去这个值就好

    不过异象石最后的答案要/2;

    至于维护的话用set就好

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const int maxn = 1e5+10;
      5 int n,head[maxn],dfsn[maxn],id[maxn],size,dp[maxn][30],cnt=0,maxd,deep[maxn],k,m;
      6 
      7 ll dis[maxn][30];
      8 
      9 set<int> s;
     10 
     11 set<int> ::iterator it,qi,ho; 
     12 
     13 struct edge{
     14     int v,w,nex;
     15 }e[maxn<<1];
     16 
     17 void adde(int u,int v,int w){
     18     e[size].v=v;e[size].w=w;e[size].nex=head[u];head[u]=size++;
     19 }
     20 
     21 void bfs(int u){
     22     queue<int> q;q.push(u);
     23     while(!q.empty()){
     24         u=q.front();q.pop();
     25         if(dp[u][0]!=-1) maxd=max(maxd,deep[u]=deep[dp[u][0]]+1);
     26         for(int i=head[u];~i;i=e[i].nex){
     27             int v=e[i].v;if(v==dp[u][0]) continue;
     28             dp[v][0]=u;dis[v][0]=e[i].w;
     29             q.push(v);
     30         }
     31     }
     32 }
     33 
     34 void doubling(){
     35     for(int j=1;j<=k;j++)
     36         for(int i=1;i<=n;i++)
     37             if(dp[i][j-1]!=-1) dp[i][j]=dp[dp[i][j-1]][j-1],dis[i][j]=dis[i][j-1]+dis[dp[i][j-1]][j-1];
     38 }
     39 
     40 void dfs(int u){
     41     dfsn[++cnt]=u;id[u]=cnt;
     42     for(int i=head[u];~i;i=e[i].nex){
     43         int v=e[i].v;
     44         if(!id[v]) dfs(v);
     45     }
     46 }
     47 
     48 char getc(){
     49     char ch=getchar();while(ch!='+'&&ch!='-'&&ch!='?') ch=getchar();
     50     return ch;
     51 }
     52 
     53 ll lca(int x,int y){
     54     ll ans=0;
     55     if(deep[x]<deep[y]) swap(x,y);
     56     for(int i=k;i>=0;i--) 
     57         if(dp[x][i]!=-1&&deep[dp[x][i]]>=deep[y]) ans+=dis[x][i],x=dp[x][i];
     58     if(x==y) return ans;
     59     for(int i=k;i>=0;i--)
     60     if(dp[x][i]!=dp[y][i]){
     61         ans+=dis[x][i]+dis[y][i];
     62         x=dp[x][i],y=dp[y][i];
     63     }
     64     return ans+dis[x][0]+dis[y][0];
     65 }
     66 
     67 int main(){
     68     //freopen("in.txt","r",stdin);
     69     //freopen("out.txt","w",stdout);
     70     scanf("%d",&n);
     71     memset(head,-1,sizeof(head));
     72     memset(dp,-1,sizeof(dp));
     73     for(int i=1;i<n;i++){
     74         int u,v,w;
     75         scanf("%d%d%d",&u,&v,&w);
     76         adde(u,v,w);adde(v,u,w);
     77     }
     78     bfs(1);
     79     k=(int) (log(maxd)/log(2));
     80     doubling();
     81     dfs(1);
     82     ll ans=0;scanf("%d",&m);
     83     while(m--){
     84         char a=getc();int u;
     85         if(a=='+'){
     86             scanf("%d",&u);
     87             if(s.empty()){
     88                 s.insert(id[u]);
     89             }
     90             else {
     91                 s.insert(id[u]);
     92                 it=s.find(id[u]);
     93                 qi=it;if(qi==s.begin()) {qi=s.end();qi--;}
     94                 else qi--;
     95                 ho=it;ho++;if(ho==s.end()) ho=s.begin();
     96                 ll aa=lca(dfsn[*qi],dfsn[*it]);
     97                 ll bb=lca(dfsn[*it],dfsn[*ho]);
     98                 ll cc=lca(dfsn[*qi],dfsn[*ho]);
     99                 ans+=aa+bb-cc;
    100             }
    101         }
    102         else if(a=='-'){
    103             scanf("%d",&u);
    104                 it=s.find(id[u]);
    105                 qi=it;if(qi==s.begin()) {qi=s.end();qi--;}
    106                 else qi--;
    107                 ho=it;ho++;if(ho==s.end()) ho=s.begin();
    108                 ll aa=lca(dfsn[*qi],dfsn[*it]);
    109                 ll bb=lca(dfsn[*it],dfsn[*ho]);
    110                 ll cc=lca(dfsn[*qi],dfsn[*ho]);        
    111                 ans-=aa+bb-cc;        
    112                 s.erase(id[u]);
    113         }
    114         else printf("%lld
    ",ans/2);
    115     }
    116     return 0;
    117 }
    View Code

    至于寻宝游戏就在输入时处理下就好,其他一样的(输出时不除二)

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const int maxn = 1e5+10;
      5 int n,head[maxn],dfsn[maxn],id[maxn],size,dp[maxn][30],cnt=0,maxd,deep[maxn],k,m,vis[maxn];
      6 
      7 ll dis[maxn][30];
      8 
      9 set<int> s;
     10 
     11 set<int> ::iterator it,qi,ho; 
     12 
     13 struct edge{
     14     int v,w,nex;
     15 }e[maxn<<1];
     16 
     17 void adde(int u,int v,int w){
     18     e[size].v=v;e[size].w=w;e[size].nex=head[u];head[u]=size++;
     19 }
     20 
     21 void bfs(int u){
     22     queue<int> q;q.push(u);
     23     while(!q.empty()){
     24         u=q.front();q.pop();
     25         if(dp[u][0]!=-1) maxd=max(maxd,deep[u]=deep[dp[u][0]]+1);
     26         for(int i=head[u];~i;i=e[i].nex){
     27             int v=e[i].v;if(v==dp[u][0]) continue;
     28             dp[v][0]=u;dis[v][0]=e[i].w;
     29             q.push(v);
     30         }
     31     }
     32 }
     33 
     34 void doubling(){
     35     for(int j=1;j<=k;j++)
     36         for(int i=1;i<=n;i++)
     37             if(dp[i][j-1]!=-1) dp[i][j]=dp[dp[i][j-1]][j-1],dis[i][j]=dis[i][j-1]+dis[dp[i][j-1]][j-1];
     38 }
     39 
     40 void dfs(int u){
     41     dfsn[++cnt]=u;id[u]=cnt;
     42     for(int i=head[u];~i;i=e[i].nex){
     43         int v=e[i].v;
     44         if(!id[v]) dfs(v);
     45     }
     46 }
     47 
     48 /*char getc(){
     49     char ch=getchar();while(ch!='+'&&ch!='-'&&ch!='?') ch=getchar();
     50     return ch;
     51 }*/
     52 
     53 ll lca(int x,int y){
     54     ll ans=0;
     55     if(deep[x]<deep[y]) swap(x,y);
     56     for(int i=k;i>=0;i--) 
     57         if(dp[x][i]!=-1&&deep[dp[x][i]]>=deep[y]) ans+=dis[x][i],x=dp[x][i];
     58     if(x==y) return ans;
     59     for(int i=k;i>=0;i--)
     60     if(dp[x][i]!=dp[y][i]){
     61         ans+=dis[x][i]+dis[y][i];
     62         x=dp[x][i],y=dp[y][i];
     63     }
     64     return ans+dis[x][0]+dis[y][0];
     65 }
     66 
     67 int main(){
     68     //freopen("in.txt","r",stdin);
     69     //freopen("out.txt","w",stdout);
     70     scanf("%d",&n);scanf("%d",&m);
     71     memset(head,-1,sizeof(head));
     72     memset(dp,-1,sizeof(dp));
     73     for(int i=1;i<n;i++){
     74         int u,v,w;
     75         scanf("%d%d%d",&u,&v,&w);
     76         adde(u,v,w);adde(v,u,w);
     77     }
     78     bfs(1);
     79     k=(int) (log(maxd)/log(2));
     80     doubling();
     81     dfs(1);
     82     ll ans=0;
     83     while(m--){
     84         //char a=getc();
     85         int u;scanf("%d",&u);
     86         if(!vis[u]){
     87             vis[u]=1;
     88             if(s.empty()){
     89                 s.insert(id[u]);
     90             }
     91             else {
     92                 s.insert(id[u]);
     93                 it=s.find(id[u]);
     94                 qi=it;if(qi==s.begin()) {qi=s.end();qi--;}
     95                 else qi--;
     96                 ho=it;ho++;if(ho==s.end()) ho=s.begin();
     97                 ll aa=lca(dfsn[*qi],dfsn[*it]);
     98                 ll bb=lca(dfsn[*it],dfsn[*ho]);
     99                 ll cc=lca(dfsn[*qi],dfsn[*ho]);
    100                 ans+=aa+bb-cc;
    101             }
    102         }
    103         else if(vis[u]){
    104                 vis[u]=0;
    105                 it=s.find(id[u]);
    106                 qi=it;if(qi==s.begin()) {qi=s.end();qi--;}
    107                 else qi--;
    108                 ho=it;ho++;if(ho==s.end()) ho=s.begin();
    109                 ll aa=lca(dfsn[*qi],dfsn[*it]);
    110                 ll bb=lca(dfsn[*it],dfsn[*ho]);
    111                 ll cc=lca(dfsn[*qi],dfsn[*ho]);        
    112                 ans-=aa+bb-cc;        
    113                 s.erase(id[u]);
    114         }
    115          printf("%lld
    ",ans);
    116     }
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    UIStoryBoard 中修改控件borderColor
    iOS自定义AlertView 与 ActionSheet 遮罩提示+弹出动画
    iOS开发 UIWebView+JavaScript 交互总结
    【注入攻击】SQL注入(不完整总结)
    [内存溢出]栈溢出基础版
    [Windows驱动开发]之内存管理
    [找工作]程序员面试宝典【笔记】(part 1)
    [Windows安装]安装程序无法创建新的系统分区,也无法定位现有系统分区
    M1卡分析
    [逆向/壳]脱壳方法
  • 原文地址:https://www.cnblogs.com/plysc/p/10496458.html
Copyright © 2020-2023  润新知