1. 程式人生 > >2018.10.14牛客noip提高組模擬賽(第五場)

2018.10.14牛客noip提高組模擬賽(第五場)

A-同餘方程

題目xx[l1,r1][l1,r1]yy[l2,r2][l2,r2]中的正整數,求方程xy)0(modm)(x\ \bigoplus\ y)\ \equiv0\pmod{m} ()(\bigoplus表示異或) 的解數

結果mod998244353mod\ 998244353

solution:

首先可以將區間轉化成字首和,這樣我們只要考慮[0,a][0,a][0,b][0,b]的答案,考慮一個區間異或另一個區間最後的答案區間到底是什麼,有了這個只要除以m

m就是答案了..

如果一個區間[a,a+2n1][a,a+2^n-1][b,b+2m1][b,b+2^m-1]異或起來的答案區間,其中aa的後nn位和bb的後mm位為00,假設n>mn>m,那麼答案區間就是[ab,ab+2n1][a\ \bigoplus\ b,a\ \bigoplus\ b\ +2^n-1],每個數對應有2m2^m種,因為每個bb都有對應的aa來異或到區間內的某個數,所以列舉每一位11,算出答案區間更新答案

注意因為l1,l2l1,l2

,l200的情況,所以可以都看成開區間

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
LL l1,l2,r1,r2,m;
const int mod=998244353;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'
?-1:1,c=getchar(); while(c<='9' && c>='0') x=x*10+c-'0',c=getchar(); return x*f; } inline LL solve(LL a,LL b){ LL ans=0,mx,mn,ql,qr; for(int i=0;i<=62;i++) if((a>>i)&1) for(int j=0;j<=62;j++) if((b>>j)&1){ LL x1=(1LL<<i),x2=(1LL<<j); mx=max(x1-1,x2-1),mn=min(x1,x2); ql=((a^x1)^(b^x2))&(~mx); qr=ql|mx; LL now=(qr/m-ql/m)%mod; if(ql%m==0) (++now)%=mod; (ans+=mn%mod*now%mod)%=mod; } return ans; } int main(){ scanf("%lld%lld%lld%lld%lld",&l1,&r1,&l2,&r2,&m); LL ans=solve(r1+1,r2+1)-solve(r1+1,l2)-solve(l1,r2+1)+solve(l1,l2); ans=(ans%mod+mod)%mod; printf("%lld\n",ans); return 0; }

B-旅遊

在可憐的計劃中,可憐一共打算遊玩 n 個景點,這些景點被 m 條雙向道路聯通(即任何兩個景點之間都能通過道路直接或者間接到達)。第 i 條道路的長度為 2i。

因為這 n 個景點中,只有 1 號景點在機場附近,所以可憐想要制定一個從 1 號點出發,沿著道路一路遊玩,並在最後回到 1 號點的遊覽計劃。同時因為每一條道路都有不一樣的風景,於是可憐想要在這個計劃中,經過每一條道路至少一次(只要從一個方向走過就算經過過這條道路)。

令一個遊覽計劃的疲勞度為行走長度的總和(多次經過的邊長度被多次計算),可憐想要計算所有滿足條件的遊覽計劃中疲勞度的最小值。

solution:

因為這個邊權十分特殊,有一個結論就是,求出一個最小生成樹,所有非樹邊一定只用經過一次(因為樹邊和一定小於這個非樹邊),然後每個非樹邊可以看成覆蓋了u,vu,v的一條路徑,每個點需要被覆蓋偶數次才能保證回到11號節點,所以只要看這個點被覆蓋次數是奇數或者偶數就好了..如果是奇數這個樹邊就要走一次偶數就要走兩次

longlong\color{red}以後要是再手懶乘爆long\ long 就錘死自己!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 500005
#define LL long long
using namespace std;
int n,m,fa[N],cnt=1,head[N],mark[N];
bool used[N<<1];
LL ans,val[N];
const int mod=998244353;

inline int rd(){
	int x=0,f=1;char c=' ';
	while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
	while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
	return x*f;
}

struct EDGE{
	int to,nxt; LL w;
}edge[N<<1];
inline void add(int x,int y,LL z){
	edge[++cnt].to=y; edge[cnt].w=z; edge[cnt].nxt=head[x]; head[x]=cnt;
}

inline int find(int x){
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

inline void dfs(int u,int fr){
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!used[i] || v==fr) continue;
		dfs(v,u);
		if(mark[v]) (ans+=edge[i].w)%=mod;
		else (ans+=edge[i].w*2%mod)%=mod;
		mark[u]^=mark[v];
	} return;
}

int main(){
	n=rd(); m=rd(); val[0]=1;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++){
		int x=rd(),y=rd(); val[i]=(val[i-1]<<1)%mod;
		add(x,y,val[i]); add(y,x,val[i]);
		int u=find(x),v=find(y);
		if(u==v) continue;
		fa[u]=v; used[cnt]=used[cnt^1]=true;
	}
	for(int i=2;i<=cnt;i+=2)
		if(!used[i]){
			(ans+=edge[i].w)%=mod;
			mark[edge[i].to]^=1;
			mark[edge[i^1].to]^=1;
		}
	dfs(1,0);
	printf("%lld\n",ans);
	return 0;
}

C-串串

給定非負整數a,b,c,d,求有多少對01串(S,T),滿足以下條件:

- S 由 a 個 0 , b 個 1 組成
- T 由 c 個 0 , d 個 1 組成
- T 可以由 S 刪掉一些字元得到

由於答案可能過大,你只需要輸出答案對 1000000007 取模後的值

solution:

一眼看上去就感覺是組合數,奈何功力不夠最後沒有調出來

很容易想到對於不同的TT都是一樣的,一共有Cc+ddC_{c+d}^dTT,對每個TT都可以新增一些字元變成一個SS,如何保證不算重呢,我們可以限制TT必須是SS中同樣的子序列中字典序最小的那個,可以發現如果在TT中插入00,只能把它插入11的前面,因為插入00前面就不是字典序最小的了,11的情況同理,這就可以看成隔板法,如何組合數求一下就好了,但是注意如果放在TT的後面就可以隨便放了,所以列舉在後面放i0j1i個0,j個1,那麼
ans+=Ci+jiCaci+d1d1Cbdj+c1c1ans+=C_{i+j}^i*C_{a-c-i+d-1}^{d-1}*C_{b-d-j+c-1}^{c-1}

特判一下c=0d=0c=0和d=0的情況就好了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 4005
#define LL long long
using namespace std;
int a,b,c,d,n,m;
LL ans,fac[maxn],inv[maxn];
const int mod=1e9+7;

inline LL qpow(LL x,int k){
	LL ret=1;
	while(k){
		if(k&1) (ret*=x)%=mod;
		(x*=x)%=mod; k>>=1;
	} return ret;

            
           

相關推薦

2018.10.14noip提高模擬

A-同餘方程 題目:xxx為[l1,r1][l1,r1][l1,r1],yyy為[l2,r2][l2,r2][l2,r2]中的正整數,求方程(x⨁y)≡0(modm)(x\ \bigoplus\ y)\ \equiv0\pmod{m}(x⨁y)≡0(modm)

計蒜 2017 NOIP 提高模擬Day1 T1 小X的質數 線性篩素數

範圍 線性篩 mat 需要 接下來 包含 能夠 數字 bottom 小 X 是一位熱愛數學的男孩子,在茫茫的數字中,他對質數更有一種獨特的情感。小 X 認為,質數是一切自然數起源的地方。 在小 X 的認知裏,質數是除了本身和 1 以外,沒有其他因數的數字。 但由於小 X

提高模擬 T3 洞穴附bitset介紹

main \n std 個數 fin 輸出 1的個數 define 聲明 就是DP。 我們可以很簡單的想到要枚舉中間點,進行邊數的轉移。 但是因為邊長數據範圍很大,所以我們考慮log的倍增。 狀態設計為\(dp[i][j][k]\),為從節點\(i\)走\(2^k\)

計蒜 2017 NOIP 提高模擬題解

最近做了一下這個,所以來寫份題解。 day1 T1 以前做過差不多的題,就是把矩陣轉45度,然後就可以二維字首和了。 T2 一條邊對答案的貢獻即經過它的路徑的總條數,就等於刪去這條邊後得到

計蒜 2017 NOIP 提高模擬Day1 A. 鄰家男孩

一道非常水的博弈論題目。 觀察樣例給出的最優方案,就是凡打出牌的時候鄰家男孩不出牌,直到凡打出最後一張牌的時候鄰家男孩開始出牌,這樣對兩者的方案都是最優的。所以可以得到 n=(a-1)-(b+1)

計蒜 2017 NOIP 提高模擬Day2

T1:劫富濟貧 這題一開始hash做的,超時 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<map&g

計蒜NOIP2017提高模擬day1

種類數 sca double 發的 ide %d ram 同時 需要 T1:小X的質數 小 X 是一位熱愛數學的男孩子,在茫茫的數字中,他對質數更有一種獨特的情感。小 X 認為,質數是一切自然數起源的地方。 在小 X 的認知裏,質數是除了本身和 1 以外,沒有其他因數的數

計蒜NOIP2017提高模擬day2-小區劃分

ant abs set day2 name anti nan turn space 傳送門 dp,註意邊界 1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm>

網-程式語言初學練習賽題解

https://ac.nowcoder.com/acm/contest/312#question   只說可說的   D進位制A+B 十六進位制用%x,八進位制用%o   J競選社長 #include <stdio.h> #i

2018年全國多校演算法寒假訓練營練習比賽題解

#include <bits/stdc++.h> using namespace std; const int maxn = 110000; int n; int A, B; int a[maxn]; map<int, int> belong; map<i

2018年全國多校演算法寒假訓練營練習比賽D集合問題詳解

題目描述 給你a,b和n個數p[i],問你如何分配這n個數給A,B集合,並且滿足: 若x在集合A中,則a-x必須也在集合A中。若x在集合B中,則b-x必須也在集合B中。輸入描述:第一行 三個數 n a b  1<=n<=1e5  1<=a,b<=1e9

【比賽報告】2018.10.31網線上[NOIP賽前集訓營-提高] NOIP練習賽卷二十八

題目連結 #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const ll mod=998244353; ll m,

NOIP提高R1 C保護(主席樹)

sin inline swap number node oid ima nts info 題意 題目鏈接 Sol Orz lyq 我們可以把一支軍隊(u, v)拆分為兩個(u, lca)和(v, lca) 考慮一個點x,什麽時候軍隊對它有貢獻,肯定是u或v在他

【題解】[NOIP賽前集訓營-提高]A.同餘方程 位運算

#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const ll mod=998244353; ll m,l1,l2,r1,r2; ll

【題解】[NOIP賽前集訓營-提高]B.旅遊 最小生成樹

題目連結 #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=5e5+10,mod=998244353; inlin

【題解】[NOIP賽前集訓營-提高]C.串串 合數

題目連結 #include<cstdio> const int N=4e3+10,mod=1e9+7; int a,b,c,d,fac[N],inv[N],ans; int C(int n,int m) { if(n<0||m<0)return

NOIP賽前集訓營-普及A題

題目連結:https://www.nowcoder.com/acm/contest/169/A 本題求在1-n範圍內ad的個數,d為大於等於2的正整數,a為1-n範圍內正整數。 本題使用的方法是篩法,可以聯想素數篩。就是a從1開始,先求出所以以a為底的ad並判斷

網NowCoder 2018年全國多校算法寒假訓練營練習比賽A.逆序數 B.Big Water Problem(線段樹-區間查詢求和和單點更新) F.The Biggest Water Problem H.Tree Recovery(線段樹-區間查詢求和和區間更新)

numbers col 如果 -o img 數組 數據 .html log 隨便補了幾道題,可能也就能寫出來這幾道吧。最近被搜索虐爆了,要抓緊去看搜索,隨便寫寫就溜,備忘一下線段樹新的板子(以前的不好用,太垃圾了) A.逆序數 時間限制:C/C+

2018年9月15日提高模擬 T1 購物

大意 給定nn件商品,現在你有kk張降價券,可以讓aiai降至bibi在購買金額不超過mm最多能購買的物品數量 思路 首先顯然可以發現,用降價券是永遠比不用要好的,所以我們在一開始優先選擇

2018年9月15日提高模擬 T2 拆網線

大意 給定一張nn個點,n−1n−1條邊的無向聯通圖,現要在圖中至少有一個由mm個點組成的聯通分量中的點數必須不小於2的情況下,割去儘量多的邊。 思路 樹形dpdp 一條邊可以用兩隻企鵝