日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

發(fā)布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

不知道為什么bzoj沒有HAOI2017

題目描述

Anihc國有n個城市,這n個城市從1~n編號,1號城市為首都。城市間初始時有m條高速公路,每條高速公路都有一個非負整數(shù)的經(jīng)濟影響因子,每條高速公路的兩端都是城市(可能兩端是同一個城市),保證任意兩個城市都可以通過高速公路互達。

國正在籌劃“八縱八橫”的高鐵建設(shè)計劃,計劃要修建一些高速鐵路,每條高速鐵路兩端也都是城市(可能兩端是同一個城市),也都有一個非負整數(shù)的經(jīng)濟影響因子。國家還計劃在“八縱八橫”計劃建成之后,將“一帶一路”擴展為“一帶_路一環(huán)”,增加“內(nèi)陸城市經(jīng)濟環(huán)”即選擇一條從首都出發(fā)沿若一系列高鐵與高速公路走的路徑,每條高鐵或高速公路可以經(jīng)過多次,每座城市也可以經(jīng)過多次,最后路徑又在首都結(jié)束。令“內(nèi)陸城市經(jīng)濟環(huán)”的GDP為依次將這條路徑上所經(jīng)過的高鐵或高速公路的經(jīng)濟影響因子異或起來(一條路經(jīng)過多次則會被計算多次)。

現(xiàn)在Anihc在會議上討論“八縱八橫”的建設(shè)計劃方案,他們會不斷地修改計劃方案,希望你能實時反饋對于當(dāng)前的“八縱八橫”的建設(shè)計劃的方案“內(nèi)陸城市經(jīng)濟環(huán)”的最大是多少。

初始時,八縱八橫1計劃中不包含任何—條高鐵,有以下3種操作

  • Add x y z

在計劃中給在城市x和城市y之間建設(shè)一條高鐵,其經(jīng)濟影響因子為z,如果這是第k個Add操作,則將這條高鐵命名為k號高鐵

  • Cancel k

將計劃中的k號高鐵取消掉,保證此時k號高鐵一定存在

  • Change k z

表示將第k號高鐵的經(jīng)濟影響因子更改為z,保證此時k號高鐵一定存在

輸入輸出格式

輸入格式:

第一行3個整數(shù)n,m,P,表示城市個數(shù).高速公路條數(shù).操作個數(shù)

接下來m行.每行3個整數(shù)表示高速公路的信息。

接下來P行.每行為一個操作

注意:輸入的所有經(jīng)濟影響因子都將以二進制的形式從高位到低位給出。

?

輸出格式:

第一行一個整數(shù).表示如果不修建任何高鐵,“內(nèi)陸城市經(jīng)濟環(huán)”的GDP最大值

接下Q行.每行一個整數(shù).表示進行了對應(yīng)的每一個操作之后.對于當(dāng)前的計劃.“內(nèi) 陸城市經(jīng)濟環(huán)”的CDP最大值。

注意:輸出的答案也要以二進制的形式從高位到低位給出。

說明

【數(shù)據(jù)規(guī)模與約定】

令所有的經(jīng)濟因子二進制表示的最多位數(shù)為len.數(shù)據(jù)滿足以下表格

數(shù)據(jù)點    n的規(guī)模    m的規(guī)模    Q的規(guī)模    len的規(guī)模    備注
1    <=5    <=8    0    <=31 2 <= 100 =n + 1 0 <= 100 3 <= 100 <= 100 0 <= 100 4 <= 500 <= 500 0 <= 1000 5 <= 100 <= 100 <= 100 <= 200 只存在 Add搡作 6 <= 500 <= 500 <= 200 <= 1000 7 <= 100 <= 100 <= 1000 <= 200 8 <= 500 <= 500 <= 1000 <= 1000 9 <= 500 <= 500 <= 1000 <= 1000 10 <= 500 <= 500 <= 1000 <= 1000 

對于所有的數(shù)據(jù)保證:n,m<=500,Q,len<=1000,1<x,y<n.且Add操作不超過500個.兩個城市之間可能有多條高速公路或高鐵,高速公路或高鐵的兩端可能是同一個城市(即 有重邊.有自環(huán))。


題目大意

初始給定一張無向連通圖,每次操作動態(tài)加、刪、修改一條邊,詢問操作后經(jīng)過根的環(huán)最大異或價值,允許離線。

題目分析

首先考慮不修改是個怎么一回事。這個無向連通圖的套路參考WC2011 XOR:因為整張圖始終保持連通,那么先對原圖求一顆生成樹,再將所有的環(huán)都放在線性基里,答案就是全局線性基的最大值。

現(xiàn)在相當(dāng)于每條邊有各自的存在時間,那么這就符合線段樹分治的模型:“在時間軸上,每一個時間點的答案基于若干個給定元素”。

這里有個線段樹分治的撤銷小問題。最初我還在想線性基怎么撤銷,后來發(fā)現(xiàn)$Q\log Q$次的分治每次開一個線性基,在過程里下傳就可以了。

于是將以上兩者相結(jié)合就可以了。

打掛的兩點:

  • 記$tag[x]$為第$x$條插入的邊在vector中的位置,$tag[x]$在邊change(即再開一條邊的時候)和$x$弄混了
  • vector里$w$記錄的是整個環(huán)的異或值,因此要記錄環(huán)上的那一條非樹邊來處理change操作

?

  1 #include<bits/stdc++.h>
  2 typedef std::bitset<1003> bit;
  3 const int maxn = 535;
  4 const int maxm = 1035;
  5 const int maxq = 1035;
  6 const int maxOpt = 10035;
  7 
  8 struct Opt
  9 {
 10     int l,r;
 11     bit w,rin;
 12     Opt(int a=0, int b=0, bit c=bit(), bit d=bit()):l(a),r(b),w(c),rin(d) {}
 13 }sv[maxm];
 14 struct Edge
 15 {
 16     int v;
 17     bit w;
 18     Edge(int a=0, bit b=bit()):v(a),w(b) {}
 19 }edges[maxm];
 20 struct LinearBasis
 21 {
 22     bit p[1003];
 23     void insert(bit w)
 24     {
 25         for (int i=1000, chk=0; i>=0&&!chk; i--)
 26             if (w[i]){
 27                 if (p[i].any()) w ^= p[i];
 28                 else p[i] = w, chk = 1;
 29             }
 30     }
 31     void query()
 32     {
 33         bit ans = bit();
 34         int pos = 0;
 35         for (int i=1000; i>=0; i--)
 36         {
 37             if (ans[i]==0) ans ^= p[i];
 38             if (ans[i]&&!pos) pos = i;
 39         }
 40         for (int i=pos; i>=0; i--) putchar(ans[i]?'1':'0');
 41         puts("");
 42     }
 43 };
 44 typedef std::vector<Opt> vec;
 45 int n,m,T,cnt;
 46 int fat[maxn],tag[maxq];
 47 int edgeTot,head[maxn],nxt[maxm];
 48 bit dis[maxn],tmp;
 49 char str[13];
 50 vec opt;
 51 
 52 int read()
 53 {
 54     char ch = getchar();
 55     int num = 0, fl = 1;
 56     for (; !isdigit(ch); ch=getchar())
 57         if (ch=='-') fl = -1;
 58     for (; isdigit(ch); ch=getchar())
 59         num = (num<<1)+(num<<3)+ch-48;
 60     return num*fl;
 61 }
 62 void read(bit &x)
 63 {
 64     char str[1035];
 65     scanf("%s",str+1), x = bit();
 66     for (int i=strlen(str+1), j=0; i>=1; i--)
 67         x[j] = str[i]-'0', ++j;
 68 }
 69 int find(int x){return x==fat[x]?x:fat[x]=find(fat[x]);}
 70 void addedge(int u, int v, bit w)
 71 {
 72     edges[++edgeTot] = Edge(v, w), nxt[edgeTot] = head[u], head[u] = edgeTot;
 73     edges[++edgeTot] = Edge(u, w), nxt[edgeTot] = head[v], head[v] = edgeTot;
 74 }
 75 void dfs(int x, int fa, bit c)
 76 {
 77     dis[x] = c;
 78     for (int i=head[x]; i!=-1; i=nxt[i])
 79     {
 80         int v = edges[i].v;
 81         if (v!=fa) dfs(v, x, c^edges[i].w);
 82     }
 83 }
 84 void solve(int l, int r, vec opt, LinearBasis bas)
 85 {
 86     vec L,R;
 87     int mid = (l+r)>>1;
 88     for (int i=0, mx=opt.size(); i<mx; i++)
 89         if (opt[i].l <= l&&r <= opt[i].r) bas.insert(opt[i].w);
 90         else{
 91             if (opt[i].l <= mid) L.push_back(opt[i]);
 92             if (opt[i].r > mid) R.push_back(opt[i]);
 93         }
 94     if (l==r) bas.query();
 95     else solve(l, mid, L, bas), solve(mid+1, r, R, bas);
 96 }
 97 int main()
 98 {
 99     memset(head, -1, sizeof head);
100     n = read(), m = read(), T = read();
101     for (int i=1; i<=n; i++) fat[i] = i;
102     for (int i=1,u,v; i<=m; i++)
103     {
104         u = read(), v = read(), read(tmp);
105         if (find(u)!=find(v))
106             fat[fat[u]] = fat[v], addedge(u, v, tmp);
107         else sv[++cnt] = Opt(u, v, tmp);
108     }
109     dfs(1, 0, bit());
110     for (int i=1; i<=cnt; i++)
111         opt.push_back(Opt(0, T, sv[i].w^dis[sv[i].l]^dis[sv[i].r]));
112     for (int i=1,cnt=0,u,v; i<=T; i++)
113     {
114         scanf("%s",str);
115         if (str[0]=='A'){
116             u = read(), v = read(), read(tmp);
117             opt.push_back(Opt(i, T, dis[u]^dis[v]^tmp, tmp));
118             tag[++cnt] = opt.size()-1;
119         }else if (str[1]=='h'){
120             u = read(), read(tmp), opt[tag[u]].r = i-1;
121             opt.push_back(Opt(i, T, tmp^opt[tag[u]].rin^opt[tag[u]].w, tmp));
122             tag[u] = opt.size()-1;
123         }else opt[tag[read()]].r = i-1;
124     }
125     solve(0, T, opt, LinearBasis());
126     return 0;
127 }

?

?

?

?

END

轉(zhuǎn)載于:https://www.cnblogs.com/antiquality/p/10263632.html

總結(jié)

以上是生活随笔為你收集整理的【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。