NOI Online 1 提高組 序列

2022-06-06 05:57:08 字數 1099 閱讀 1470

luogu p6185 noi online #1 序列

將其轉化為圖論題。

定義:\(u,v\)為\(a_i\)所代表的點 \(u',v'\)為\(b_i\)所代表的點

對於操作\(2\),將其視為一種權值搬運的操作,從\(u\)到\(v\)或者反過來轉移點權。那麼我們對\(u,v\)和\(u',v'\)連一條無向邊,顯然對於乙個連通塊內的所有點都可以直接或間接的相互轉移權值。

在\(u,v\)與\(u',v'\)兩者之間做權值轉移時等價的,所以要連兩條無向邊。

對於操作\(1\),我們可以將其轉化為一種特殊的操作\(2\),可以發現我們只關心當前權值和目標權值的相對大小。所以操作\(u+1,v+1\)等價於\(u'-1,v+1\)或者\(u+1,v'-1\),也就是轉化為了操作2。

按照這樣的方式建圖,可以發現每乙個連通塊內的所有點,要麼只有\(a\)裡面的點,要麼只有\(b\)裡面的點。如果兩者都有,其數量一定相等。

應該如何檢驗答案呢?

如果\(i,i'\)位於同乙個連通塊,意味著連通塊中必然有等數量的\(a\)點和\(b\)點。該連通塊有解,當且僅當其權值和為偶數。

反之,如果位於兩個連通塊內,則只需要兩個連通塊權值和相等即說明有解。

用並查集找連通塊即可。複雜度\(o(tn)\)

#include#includeusing namespace std;

int fa[200005],u,v,t,val[200005],n,m,t;

int getf(int v)

void merge(int x,int y)

bool check(int x,int y)

int main()

for (int i=1;i<=n;i++) scanf("%d",&val[i+n]);

for (int i=1;i<=m;i++)

else

}bool flag=true;

for (int i=1;i<=n;i++)

}else}}

printf(flag?"yes\n":"no\n");

}return 0;

}

NOI Online 1 提高組 氣泡排序

這個題很繞,記數字i前面有cns i 個數字比他大,逆序對個數就是sigmi cns i 反轉k次就是讓cns i k i 1 i n 而且cns i 不能有負數 利用兩個線段樹維護一下,就是有點繞。include include include include includeusing names...

NOI Online 1 入門組 魔法

全網都是矩陣快速冪,我只會倍增dp 其實這題與 acwing 345.牛站 還是比較像的,那題可以矩陣快速冪 倍增,這題也行。先 floyd 預處理兩點之間不用魔法最短距離 d 複雜度 o n 3 然後預處理兩點之間至多用乙個魔法的最短距離 w 初始為 w d 列舉 i,j 和一條邊 u,v,t w...

NOI Online 1 提高組 T2 氣泡排序

對乙個序列給定兩種操作,交換兩個相鄰的數,求經過k kk輪氣泡排序後逆序對個數。一輪氣泡排序指的是氣泡排序內層迴圈執行一遍。可以發現,乙個數能進行交換,當且僅當前面沒有比它大的數。而且每輪前面比它大的數都會少1 11,因為前面有且僅有乙個最大的數到它的後面,其他較大且能交換的數一定遇到這個最大的數停...