<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [Codeforces Round 857 (Div. 1)][Codeforces 1801A~1801G(部分,已更新A~D、F)]

      FST哩,好似!本來能+80的,現(xiàn)在只加了30,相當(dāng)于掉了50分捏

      1801A - The Very Beautiful Blanket

      題目大意:要求構(gòu)造一個 \(n\times m\) 的矩陣 \(B\),使得對任意一個 \(4\times 4\) 的子矩陣 \(A\) 均滿足 \(A_{13} \oplus A_{14} \oplus A_{23} \oplus A_{24} = A_{31} \oplus A_{32} \oplus A_{41} \oplus A_{42}\)\(A_{13} \oplus A_{14} \oplus A_{23} \oplus A_{24} = A_{31} \oplus A_{32} \oplus A_{41} \oplus A_{42}\)

      直接令 \(A_{ij}=256\times i+j\) 即可,原理是這樣構(gòu)造可以讓任意一個 \(2\times 2\) 的子矩陣滿足異或和為零,因為在二進(jìn)制下對應(yīng)權(quán)值最低的八位代表列號,更高位代表行號,各部分都是能各自消掉的。

      #include<bits/stdc++.h>
      using namespace std;
      #define N 300
      int T,n,m,a[N][N];
      int main()
      {
      	for(int i=0;i<256*256;i++){
      		int x=i/256,y=i%256;
      		a[x][y]=i;
      	}
      	scanf("%d",&T);
      	while(T--){
      		scanf("%d%d",&n,&m);
      		printf("%d\n",n*m);
      		for(int i=0;i<n;i++)
      		for(int j=0;j<m;j++)
      			printf("%d%c",a[i][j],j<m-1?' ':'\n');
      	}
      }
      

      1801B - Buying gifts

      題目大意:有 \(n\) 個物品,每個物品有兩個權(quán)值 \(a_i,b_i\)分別表示該物品給 \(A,B\) 兩個人的權(quán)值。要求把這 \(n\) 個物品分配給兩人使得 \(|maxA-maxB|\) 盡可能小。\(maxA,maxB\) 分別表示兩人分配到物品的最大權(quán)值,每人至少要被分配一個物品。

      這題我 FST 了,原因是當(dāng)所有物品一樣的時候我全買給了 \(A\),好似!

      這種題的做法有一個慣用套路就是固定其中一維然后求解。假設(shè)我們欽定了 \(maxA\) 的值,那么可以發(fā)現(xiàn)所有 \(a_i>maxA\) 的物品都必須給 \(B\),而這時其它物品怎么選都不會影響 \(maxA\) 的值,那么在這些物品中選一個 \(b_i\)\(maxA\) 最接近的給 \(B\) 即可。

      于是就得到了一種做法,先把物品按照 \(a_i\) 排序,從小到大枚舉欽定哪一個物品是必須給 \(A\) 的,這時后面的所有物品就都得給 \(B\),可以預(yù)處理后綴 \(\max\) 求出這一部分對 \(maxB\) 的貢獻(xiàn)。而對于前面選離 \(maxA\) 最近的值,利用 \(\mathrm{multiset}\) 中的 \(\mathrm{lower\_bound}\) 亂搞即可。

      注意由于 \(a_i\) 的值可能相同,所以需要對相同的 \(a_i\) 分批處理,具體實現(xiàn)見代碼。

      \(\mathrm{Find}\) 函數(shù)中的 \(o\) 就是特判之前 FST 的情況用的。

      #include<bits/stdc++.h>
      using namespace std;
      #define N 500010
      int n,f[N],ans;
      multiset<int>s;
      struct rua
      {
      	int x,y;
      	void read(){scanf("%d%d",&x,&y);}
      	bool operator <(const rua &t)const{return x<t.x;}
      }a[N];
      int Find(int x,int y,int o)
      {
      	int res=o?1e9:abs(x-y);
      	auto it=s.lower_bound(x);
      	if(it!=s.end()){
      		int z=max(y,*it);
      		res=min(res,abs(x-z));
      	}
      	if(it!=s.begin()){
      		it--;
      		int z=max(y,*it);
      		res=min(res,abs(x-z));
      	}
      	return res;
      }
      void init()
      {
      	ans=2e9;
      	s.clear();
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++)a[i].read();
      	sort(a+1,a+n+1);
      	f[n+1]=0;
      	for(int i=n;i>=1;i--)f[i]=max(a[i].y,f[i+1]);
      	for(int i=1,j;i<=n;i=j+1){
      		j=i;
      		while(j<=n && a[j].x==a[i].x)j++;j--;
      		int x=a[i].x;
      		int y=f[j+1];
      		for(int k=i;k<=j;k++)s.insert(a[k].y);
      		for(int k=i;k<=j;k++){
      			s.erase(s.find(a[k].y));
      			ans=min(ans,Find(x,y,j==n));
      			s.insert(a[k].y);
      		}
      	}
      	printf("%d\n",ans);
      }
      int main()
      {
      	int T;
      	scanf("%d",&T);
      	while(T--)init();
      }
      

      1801C - Music Festival

      題目大意:定義一個序列 \(A\) 的價值為滿足 \(A_i=\max_{j=1}^{i}A_j\)\(i\) 的個數(shù)。給定 \(n\) 個序列,要求以任意方式將他們拼接起來,使得得到的序列價值最大。

      首先可以得到,對于每個序列,只有滿足對應(yīng)性質(zhì)的那些元素才有可能對答案產(chǎn)生貢獻(xiàn),所以首先可以在輸入的時候就對序列進(jìn)行預(yù)處理,留下一個嚴(yán)格遞增的序列。

      考慮 \(\mathrm{DP}\),令 \(f_i\) 表示以數(shù)字 \(i\) 為結(jié)尾的序列的最大價值,那么可以得到如果把某個序列 \(A\) 接在尾部,對應(yīng)的方案只能更新到 \(f_{maxA}\) 上。于是考慮把序列按照最后一個元素大小進(jìn)行排序。

      \(\mathrm{DP}\) 的過程中,考慮對每個序列枚舉該序列是從第幾個位置開始產(chǎn)生貢獻(xiàn)的。假設(shè)當(dāng)前在序列 \(A\) 中枚舉到的位置為 \(i\)(這題本人實現(xiàn)下標(biāo)是從 \(0\) 開始),序列處理后的長度為 \(k\),最大值為 \(m\),那么找到最大的 \(j\) 使得 \(j<a_i\)\(f_j\) 有值,此時 \(f_j\) 就會對 \(f_m\) 產(chǎn)生 \(f_j+k-i\) 的貢獻(xiàn),實時更新答案即可。\(j\) 的查找可以通過記錄所有當(dāng)前 \(f\) 有值的位置,\(\mathrm{lower\_bound}\) 一下即可。最后不要忘了多測清空。

      #include<bits/stdc++.h>
      using namespace std;
      #define N 200010
      int T,n,f[N];
      struct rua
      {
      	int m,k;
      	vector<int>d;
      	void init(){m=k=0;d.clear();}
      	void read(){
      		d.clear();
      		scanf("%d",&k);
      		for(int i=1;i<=k;i++){
      			int x;
      			scanf("%d",&x);
      			if(x<=m)continue;
      			d.push_back(x);
      			m=x;
      		}
      		k=d.size();
      	}
      	bool operator <(const rua &t)const{return m<t.m;}
      }a[N];
      vector<int>v;
      void init()
      {
      	int ans=0;
      	v.clear();
      	scanf("%d",&n);
      	for(int i=1;i<=n;i++){
      		a[i].init();
      		a[i].read();
      	}
      	sort(a+1,a+n+1);
      	for(int i=1;i<=n;i++){
      		for(int j=0;j<a[i].k;j++){
      			int x=a[i].d[j];
      			int k=lower_bound(v.begin(),v.end(),x)-v.begin()-1;
      			f[a[i].m]=max(f[a[i].m],a[i].k-j);
      			if(k>=0)f[a[i].m]=max(f[a[i].m],f[v[k]]+a[i].k-j);
      			ans=max(ans,f[a[i].m]);
      		}
      		v.push_back(a[i].m);
      	}
      	for(auto i:v)f[i]=0;
      	printf("%d\n",ans);
      }
      int main()
      {
      	scanf("%d",&T);
      	while(T--)init();
      }
      

      1801D - The way home

      題目大意:一個 \(n\) 個點 \(m\) 條邊的有向圖,每條邊有對應(yīng)花費。某個憨憨演唱家現(xiàn)在身上只有 \(p\) 元錢,他可以選擇在某個點 \(i\) 開演唱會以得到 \(s_i\) 的收入。問要從 \(1\) 走到 \(n\) 所需要舉辦的演唱會次數(shù)最小是多少。

      首先考慮如果回家的路徑確定了,唱歌的決策是怎樣的。可以發(fā)現(xiàn)最后肯定是在某個點 \(x\) 死命唱歌直到恰好攢夠回家的錢,然后直接走最小花費的路徑跑路。接著再倒著往回推,在這之前他肯定也是在另一個點恰好攢夠錢后再動身來到 \(x\)。所以可以得到如果已經(jīng)選定了先后在哪些位置開演唱會,那么其唱歌決策是確定的,即每次在當(dāng)前位置一直舉辦演唱會直到攢夠前往下一個位置的錢。

      于是跑 \(n\) 遍單源最短路,對所有 \((i,j)\) 預(yù)處理出從點 \(i\) 走到點 \(j\) 的最小花費 \(dis_{i,j}\)。再使用類似最短路的過程貪心選取下個演唱會的地點。那么在這一部分的最短路中,有兩個參考值,一個是 \(cost_i\) 表示到達(dá) \(i\) 這個點需要舉辦演唱會的最小次數(shù),另一個是 \(res_i\) 表示在次數(shù)最小的前提下,所剩余錢數(shù)的最大值。那么根據(jù)這兩個信息跑最短路即可,每次到點 \(x\) 時,枚舉下一個唱歌的位置 \(i\),根據(jù)當(dāng)前的 \(res_x\)\(dis_{x,i}\) 的差值以及在 \(x\) 舉辦演唱會的收入 \(s_x\) 可以得到需要舉辦演唱會的次數(shù) \(k\),直接轉(zhuǎn)移即可。最后答案就是 \(cost_n\)

      #include<bits/stdc++.h>
      using namespace std;
      #define N 810
      #define LL long long
      int T,n,m,p,b[N],vis[N];
      LL dis[N],cost[N],res[N];
      vector<pair<int,int>>d[N];
      struct rua
      {
      	int x;
      	LL cost,res;
      	bool operator <(const rua &t)const{
      		if(cost!=t.cost)return cost<t.cost;
      		return res>t.res;
      	}
      };
      set<rua>s;
      void Dij(int x)
      {
      	set<pair<LL,int>>q;
      	for(int i=0;i<=n;i++)dis[i]=1e18;
      	dis[x]=0;
      	for(int i=1;i<=n;i++)q.insert(make_pair(dis[i],i));
      	while(!q.empty()){
      		auto PI=*q.begin();
      		q.erase(q.begin());
      		int x=PI.second;
      		for(auto pi:d[x]){
      			LL nd=dis[x]+pi.second;
      			int y=pi.first;
      			if(nd<dis[y]){
      				q.erase(make_pair(dis[y],y));
      				dis[y]=nd;
      				q.insert(make_pair(dis[y],y));
      			}
      		}
      	}
      }
      LL ceil(LL x,LL y)
      {
      	if(x<0)return 0;
      	if(x%y==0)return x/y;
      	return x/y+1;
      }
      void init()
      {
      	s.clear();
      	scanf("%d%d%d",&n,&m,&p);
      	for(int i=1;i<=n;i++){
      		d[i].clear();
      		scanf("%d",&b[i]);
      		vis[i]=0;
      		cost[i]=1e18;
      		res[i]=0;
      	}
      	for(int i=1;i<=m;i++){
      		int u,v,w;
      		scanf("%d%d%d",&u,&v,&w);
      		d[u].push_back(make_pair(v,w));
      	}
      	Dij(1);
      	if(dis[n]==dis[0]){
      		printf("-1\n");
      		return;
      	}
      	cost[1]=0,res[1]=p;
      	s.insert((rua){1,cost[1],res[1]});
      	while(!s.empty()){
      		auto X=*s.begin();
      		s.erase(s.begin());
      		int x=X.x;
      		vis[x]=1;
      		Dij(x);
      		for(int i=1;i<=n;i++)if(!vis[i]){
      			LL k=ceil(dis[i]-res[x],b[x]);
      			rua tmp={i,cost[x]+k,res[x]+k*b[x]-dis[i]};
      			rua I={i,cost[i],res[i]};
      			if(tmp<I){
      				s.erase(I);
      				cost[i]=tmp.cost;
      				res[i]=tmp.res;
      				s.insert(tmp);
      			}
      		}
      	}
      	printf("%lld\n",cost[n]);
      }
      int main()
      {
      	scanf("%d",&T);
      	while(T--)init();
      }
      

      賽場上為了省空間寫了個類似于最短路套最短路的玩意orz

      1801E - Gasoline prices

      不會捏,留坑待填

      1801F - Another n-dimensional chocolate bar

      題目大意:給定一個長度為 \(n\) 的數(shù)組 \(a\) 和正整數(shù) \(k\),要求構(gòu)造一個數(shù)組 \(b\) 滿足 \(1\le b_i \le a_i\)\(\prod_{i=1}^{n}b_i \ge k\),使得 \(\lfloor \frac{a_1}{b_1} \rfloor \dotsm \lfloor \frac{a_n}{b_n} \rfloor \cdot \frac{1}{a_1 a_2 \cdots a_n} \cdot k\) 盡可能大,輸出這個最大值。

      由于 \(a_i\)\(k\) 已經(jīng)給出,所以就相當(dāng)于要在滿足條件的前提下最大化 \(\prod_{i=1}^{n}\lfloor \frac{a_i}{b_i} \rfloor\)。考慮一個樸素的 \(\mathrm{DP}\)\(f_{i,j}\) 表示當(dāng)前到第 \(i\) 個位置,對應(yīng) \(b_i\) 的前綴乘積為 \(j\) 時,\(\lfloor \frac{a_i}{b_i} \rfloor\) 乘積的最大值。這樣直接做復(fù)雜度爆炸。

      接著考慮優(yōu)化,因為要求的是 \(\prod b_i\ge k\),所以不妨把 \(\mathrm{DP}\) 改成令 \(f_{i,j}\) 表示到第 \(i\) 個位置,要求剩下 \(b_i\) 乘積 \(>j\) 的答案,這樣轉(zhuǎn)移的時候 \(j\) 的值大概就能減少的很快,每次枚舉 \(b_i\) 的值就能直接從 \(j\) 轉(zhuǎn)移到 \(\lfloor\frac{j}{b_i}\rfloor\) 上。從 \(f_{1,k-1}\) 一路轉(zhuǎn)移到 \(f_{n,0}\) 就是答案。

      這時發(fā)現(xiàn)在轉(zhuǎn)移過程中,實際上所有的 \(j\) 必然等于 \(\lfloor\frac{k-1}{x}\rfloor\)\(x\) 為某個正整數(shù)),于是考慮數(shù)論分塊預(yù)處理出所有可能的 \(j\),在這些位置間轉(zhuǎn)移即可,顯然這樣的 \(j\) 只有 \(O(\sqrt k)\) 個。而每次 \(i,j\) 能轉(zhuǎn)移到的位置數(shù)則是 \(O(\sqrt j)\) 個的,所以直接轉(zhuǎn)移的總復(fù)雜度與杜教篩類似,為 \(O(n\cdot k^{\frac{3}{4}})\)

      #include<bits/stdc++.h>
      using namespace std;
      #define N 110
      #define ld long double
      int n,m,k,x,a[N],b[N*N],id[1<<24];
      ld f[N][N*N],ans=1;
      int Fl(int x,int y){return x/y;}
      int main()
      {
      	scanf("%d%d",&m,&k);
      	ans*=k,k--;int kk=k;
      	for(int i=1;i<=m;i++){
      		scanf("%d",&x);
      		if(x>1)a[++n]=x;
      		ans/=x;
      		kk/=x;
      	}
      	if(kk)return printf("0\n"),0;
      	m=0;
      	for(int l=1,r;l<=k;l=r+1){
      		r=k/(k/l);
      		b[++m]=r;
      		id[r]=m;
      	}
      	f[0][m]=1;
      	for(int i=1;i<=n;i++){
      		f[i][0]=f[i-1][0]*a[i];
      		for(int j=1;j<=m;j++)if(f[i-1][j]){
      			x=b[j];
      			for(int l=1,r;l<=a[i];l=r+1){
      				int nxt=x/l;
      				if(nxt)r=x/nxt;else r=a[i];
      				f[i][id[nxt]]=max(f[i][id[nxt]],f[i-1][j]*Fl(a[i],l));
      			}
      		}
      	}
      	printf("%.10Lf\n",f[n][0]*ans);
      }
      
      posted @ 2023-03-10 09:29  DeaphetS  閱讀(291)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美精品aaaaaa片| 18禁黄无遮挡网站免费| AV人摸人人人澡人人超碰| 江川县| 日韩午夜福利片段在线观看| 国产精品爆乳奶水无码视频免费| 国产综合色产在线精品| 国产免费一区二区不卡| 一亚洲一区二区中文字幕| 啊轻点灬大JI巴太粗太长了欧美| 国产精品一区二区 尿失禁| 不卡在线一区二区三区视频| 久久无码中文字幕免费影院| 安康市| 欧美国产精品啪啪| 国产在线精品国偷产拍| 亚洲日韩精品无码一区二区三区| 成人综合婷婷国产精品久久蜜臀| 国产精品一区二区久久岳| 亚洲AV成人片不卡无码| 成人免费视频一区二区三区| 偷拍久久大胆的黄片视频| 精品黄色av一区二区三区| 欧美激情一区二区久久久| 亚洲成在人线在线播放无码| 国产无套内射普通话对白| 亚洲a片无码一区二区蜜桃| 十八禁午夜福利免费网站| 国产乱子伦精品免费女| 日韩精品 在线一区二区| 亚洲伊人五月丁香激情| 国产老妇伦国产熟女老妇高清| 伊人中文在线最新版天堂| 久久久精品2019中文字幕之3| 色综合久久一区二区三区| 在线播放免费人成毛片| 好紧好滑好湿好爽免费视频| 国产成人久久精品二三区| 免费区欧美一级猛片| 色偷偷亚洲女人天堂观看| 色一伊人区二区亚洲最大|