CSP校內集訓 替換遊戲(tarjan 離散化)

2022-03-17 00:07:58 字數 1962 閱讀 6483

給乙個範圍\([0,n]\),有兩種變換方式,\(+k\)或者給定的\(m\)個\(x->y\),但必須保證變換前後的數始終在範圍內,給乙個數\(x\),求出它一直變換下去(注意不能得到了乙個數之後返回上一步)可以得到的所有數的和的最大值\((n\leq 10^8 , m\leq 10^5 , k\leq n)\),多組詢問

對兩種方式建邊,顯然乙個強連通分量中的點是都可以選到的,所以相當於多次詢問求出dag中從某個點出發的最長鏈,建反邊拓撲即可

但是這道題的點數是\(10^8\)級別的,考慮到大多數連邊都是第一種很規則的連邊,所以有很多點是沒有必要的,考慮離散化

將所有數按照對\(k\)取模的值分為\(k\)組,按照第一種方式連邊後形成\(k\)條互不相交的鏈

將所有的第二種建邊和詢問用到的點離線下來離散化,即這些點需要單獨考慮,這些點將鏈分為了很多小段,把每乙個小段變成乙個點

這時就可以發現點數已經與\(n\)無關了(有\(o(m+q)\)級別的點數),連線這些點後就可以像上面的暴力一樣做了

p.s. 點權請自行用等差數列解決

#include#define n 600005

#define min(x,y) ((x)<(y)?(x):(y))

#define max(x,y) ((x)>(y)?(x):(y))

using namespace std;

typedef long long ll;

int n,m,k,ndsum;

int dfn[n],low[n],cp,col,color[n];//tarjan

int st[n],top,rd[n];//拓撲

int b[n],c[n],len;//離散化特例

ll sum[n],val[n],f[n];

vectorson[n];//新圖

struct e e[n];

int q[n];//離線詢問 和 邊

struct edge

edge[n<<2];int head[n],cnt;

void add_edge(int from,int to)

template void read(t &x)

void tarjan(int rt)

else if(!color[v]) low[rt]=min(low[rt],dfn[v]);

} if(dfn[rt]==low[rt])

--top; }}

void init()

} }queueq;

for(int i=1;i<=col;++i) if(!rd[i]) q.push(i),f[i]=sum[i];

while(!q.empty())

ll get_sum(int x,int y)//求(x,y]的和

void work()

} else

else add_edge(c[i],c[i+1]);

} }for(int i=1;i<=m;++i) add_edge(e[i].u,e[i].v); //連特殊邊

for(int i=1;i<=ndsum;++i) if(!dfn[i]) tarjan(i);

}int main()

int t; read(t);

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

//離散化

sort(b+1,b+len+1);

len=unique(b+1,b+len+1)-b-1;

ndsum=len;

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

for(int i=1;i<=t;++i) q[i]=lower_bound(b+1,b+len+1,q[i])-b;

work();

init();

for(int i=1;i<=t;++i) printf("%lld\n",f[color[q[i]]]);

return 0;

}

CSP校內集訓 打撲克

有 n 堆大小為1的撲克,支援合併兩堆撲克和查詢有多少對撲克堆滿足 size i size j leq c c 不確定 暴力做法 開桶記錄當前存在有多少個大小為 i 的堆,查詢可用樹狀陣列或者雙指標,時間複雜度 o m 2logn 或者 o m 2 優化 發現列舉大小的桶有很多是空的,實際上,可以證...

CSP校內集訓 kat(期望DP)

一本有n道題的練習冊,katarina大佬每天都會做k道題。第一天做第1k題,第二天做第2k 1題 第n k 1天做第n k 1 n道題。每道題有它的難度值,假設今天katarina大佬做的題目中最大難度為t,那麼今天katarina大佬的勞累度就是 w t 做完這本書的勞累值就是每天的勞累值之和。...

CSP校內集訓 reverse(數字DP)

給乙個範圍 l,r 求滿足 l leq n leq r 且 l leq rev n leq r 的 n 的個數,其中 rev n 表示將 n 翻轉 123 321 多組詢問 l,r leq 2 64 1 長這樣的計數問題,沒什麼懸念考慮數字dp 只設 f 表示處理到第 i 位是否頂上界似乎不太夠,因...