TJOI2018簡要題解

2022-04-30 13:15:11 字數 4545 閱讀 1079

按照時間軸建一棵線段樹即可,複雜度為\(o(m \log m)\)

#include #define n 100005

#define ll long long

#define getchar nc

using namespace std;

inline char nc()

inline ll read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

int n;

ll mod;

struct segmenttree

inline void pushup(register int x)

inline void update(register int x,register int l,register int r,register int pos,register int v)

int mid=l+r>>1;

if(pos<=mid)

update(x<<1,l,mid,pos,v);

else

update(x<<1|1,mid+1,r,pos,v);

pushup(x);

}}tr;

int main()

} return 0;

}

考慮二分答案,二分的是最大能覆蓋到的權值

這樣我們就將問題轉化成乙個dag能否被\(n+1\)條可重鏈覆蓋

這就是乙個經典問題了,先跑一下弗洛伊德傳遞閉包,然後二分圖最大匹配即可,複雜度為\(o(m^3+m^3 \log m )\)

#include #define n 505

#define getchar nc

using namespace std;

inline char nc()

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

int n,m,o[n],v[n],g[n][n],gn[n][n],link[n],vis[n];

inline bool hungary(register int x)

return 0;

}inline bool check(register int mid)

memset(link,0,sizeof(link));

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

return res<=n;

}int main()

for(register int k=1;k<=m;++k)

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

for(register int j=1;j<=m;++j)

g[i][j]|=g[i][k]&g[k][j];

sort(o+1,o+m+1);

if(check(o[m]+1))

int l=1,r=m-1;

while(l>1;

if(check(o[mid]))

l=mid;

else

r=mid-1;

}write(o[l+1]);

return 0;

}

這題和麻將是乙個套路,考的是乙個叫做dp套dp的神奇科技

發現獎章串的長度小於等於15,所以可以考慮把15位的dp陣列作為轉移的狀態

回想一下lcs的求法,dp相鄰的兩個值最多差1,可以考慮狀壓

設\(f[i][j][0/1/2]\)表示匹配到兌獎串的第\(i\)位,\(dp\)狀態為j,最後與「noi」的匹配位數為0/1/2,轉移顯然

直接做空間會炸,第一位滾一下即可,複雜度為\(o(nk2^k)\)

#include #define mod 1000000007

#define n 1005

using namespace std;

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

inline void add(register int &x,register int y)

int n,l,tot;

char s[20];

int dp[2][n],f[2][1<<15][3],ans[n];

inline void decode(register int sta)

inline int encode()

inline void trans(register int i,register int j,register int k,register char c,register int v)

add(f[i][encode()][k],v);

}int main()

\)表示處理完了\(i\)個鹼基序列,匹配到第\(j\)位的方案數,轉移顯然

空間不夠,滾動一下即可,複雜度為\(o(t \sum a_i |s|)\)

#include #define mod 1000000007

#define n 100005

using namespace std;

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

int m,n,f[2][n],now,nxt[n],ans;

char s[n],t[n];

int main()

inline int read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

inline int max(register int a,register int b)

struct edgee[n<<1];

int head[n],cnt=0;

inline void add(register int u,register int v)

; head[u]=cnt;

}int n,q,v[n],root[n];

int son[n],fa[n],size[n],dep[n],top[n],dfn[n],tim;

struct nodetr[n*80];

int tot=0;

inline void insert(register int &rt,register int pre,register int bit,register int val)

inline int query(register int a,register int b,register int bit,register int val)

int main()

^ i^\]則

\[ans=\sum_^\left(s\left(n-a_\right)-\sum_^\left(a_-a_\right)^\right)

\]珂以證明\(s(x)\)是個\(m+3\)次多項式(珂以用一次二次三次函式模擬,但嚴謹的證明還是需要通過數學歸納法的),可以用拉格朗日插值快速處理,複雜度為\(o(t m^2 \log p)\),預處理逆元的話能做到\(o(t m^2)\)

#include #define ll long long

#define mod 1000000007

#define n 55

#define getchar nc

using namespace std;

inline char nc()

inline ll read()

while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

return x*f;

}inline void write(register int x)

inline int power(register ll a,register int b)

return res;

}ll t,n,m,a[n],f[n];

inline int calc(register ll d,register int n)

return (ans+mod)%mod;

}int main()

write(ans),puts("");

}return 0;

}

題解 TJOI2018 異或

對於題目給出的兩個查詢,我們我可以將它這樣轉換 對於操作一,用dfs序將乙個子樹轉化為一段連續的區間,然後根據dfs序建立乙個trie樹,那麼查詢乙個子樹即為查詢一段區間 對於操作二,根據根到結點的路徑建立乙個trie樹,同樣也可以轉化為乙個區間查詢 於是就可以建兩個trie樹,分別對應兩個操作 結...

TJOI2018 數學計算

如果採取暴力的做法,那麼乘起來會炸longlong,除非寫個高精。再考慮乘一下逆元呢,顯然也不行,模數不一定為質數。這道題的關鍵點在於這句話,對於每乙個型別1的操作至多會被除一次 這句話的最基本的告訴了我們每次得到的答案一定是乙個整數 其次,這句話保證了可以應用線段樹解決這個問題 如果除的操作可能會...

Tjoi2018 數學計算

bzoj luogu 線段樹分治 是不是想問為什麼不暴力做?模數沒說是質數,所以不一定有逆元.然後就是要每次build一下把線段樹權值init成1,博豬不知道為什麼for就wa,build就過了 用re自動機查了下,發現還是有0.for int i 1 i 1 i s i 1 define ls x...