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

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

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

      noip模擬38

      \(\color{white}{\mathbb{深秋總有廖落處,雁歸每是菊敗時,名之以:殘菊}}\)


      pic.png

      這場比賽幾乎全場都在打暴力,幾乎人均切掉的 \(t1\) 沒有想到雙指針,\(t3\) 的暴力也沒記憶化而太過暴力


      A. a

      很容易想到同時枚舉兩行,然后算列的貢獻

      考場上只想到用數狀數組維護,但是很顯然 \(down\)\(up\) 兩條線之間區域的邊界是單調的,雙指針維護即可


      B.b

      考慮對于每個 \(i\) 計算 \(i|gcd\) 的方案數,設每一組是 \(i\) 的倍數的數有 \(cnt_j\) 個,答案為 \(\prod (cnt_j+1)-1\)

      但是此時每個 \(i\) 保存的是其所有倍數的值之和,那么考慮倒序枚舉所有數,其實大于當前數的所有數已經還原成 \(i=gcd\) 的值,那么用當前數的值減去所有倍數的值即可


      C.c

      一開始沒看見去重后是棵樹……

      首先每條邊都有多種候選顏色,但只保留三種即可,即和上一個不重,和下一個不重

      考慮點分治,從分治中心開始 \(dp\),設 \(f[i][0/1/2][0/1/2]\) 表示從中心到第 \(i\) 個點,路徑上第一條邊的顏色為第幾種,最后一條邊的顏色是第幾種的最大價值
      然后寫棵點分樹把詢問掛在點分樹上的 \(lca\) 就好了

      代碼實現
      #include<bits/stdc++.h>
      using namespace std;
      const int maxn=1e5+5;
      const int maxm=1e6+5;
      int hd[maxn],cnt,from[maxn],las[maxn],f[maxn][5][5],n,m,q,xx[maxn],yy[maxn],fa[maxn],fa1[maxn],dep[maxn],siz[maxn],rt,maxx[maxn],x,y,w,sum,sta[maxn],tp;
      bool del[maxn];
      vector<pair<int,int> >has[maxn];
      map<pair<int,int>,int>ans,mp;
      int read(){
      	int x=0,f=1;
      	char ch=getchar();
      	while(!isdigit(ch)){
      		if(ch=='-')f=-1;
      		ch=getchar();
      	}
      	while(isdigit(ch)){
      		x=x*10+ch-48;
      		ch=getchar();
      	}
      	return x*f;
      }
      struct Edge{
      	int nxt,to,val[4];
      	int numval;
      }edge[maxm];
      void add(int u,int v,int w){
      	edge[++cnt].nxt=hd[u];
      	edge[cnt].to=v;
      	edge[cnt].val[++edge[cnt].numval]=w;
      	hd[u]=cnt;
      	return ;
      }
      void dfs_w(int u,int father){
      	siz[u]=1;
      	maxx[u]=0;
      	for(int i=hd[u];i;i=edge[i].nxt){
      		int v=edge[i].to;
      		if(v==father||del[v])continue;
      		dfs_w(v,u);
      		siz[u]+=siz[v];
      		maxx[u]=max(maxx[u],siz[v]);
      	}
      	maxx[u]=max(maxx[u],sum-siz[u]);
      	if(maxx[u]<maxx[rt])rt=u;
      	return ;
      }
      void dfs_dis(int u,int father,int last,int num){
      //	cout<<u<<" "<<father<<" "<<last<<" "<<num<<endl;
      	sta[++tp]=u;
      	from[u]=num;
      	las[u]=last;
      	for(int i=hd[u];i;i=edge[i].nxt){
      		int v=edge[i].to;
      		if(v==father||del[v])continue;
      		for(int j=1;j<=edge[num].numval;j++){
      			for(int k=1;k<=edge[last].numval;k++){
      				for(int p=1;p<=edge[i].numval;p++){
      					f[v][j][p]=max(f[v][j][p],f[u][j][k]+(edge[last].val[k]!=edge[i].val[p]));
      				}
      				
      			}
      		}
      		dfs_dis(v,u,i,num);
      	}
      	return ;
      }
      void calc(int u){
      //	cout<<u<<endl;
      	tp=0;
      	for(int i=hd[u];i;i=edge[i].nxt){
      		int v=edge[i].to;
      		if(del[v])continue;
      		for(int j=1;j<=edge[i].numval;j++)f[v][j][j]=1;
      		dfs_dis(v,u,i,i);
      	}
      	
      	for(int i=0;i<has[u].size();i++){
      		int x=has[u][i].first,y=has[u][i].second,mx=0;
      //		if(u==4)cout<<x<<" "<<y<<endl;
      		if(y==u)swap(x,y);
      		if(x==u){
      			for(int j=1;j<=edge[from[y]].numval;j++){
      				for(int k=1;k<=edge[las[y]].numval;k++){
      					mx=max(mx,f[y][j][k]);
      				}
      			}
      			ans[has[u][i]]=mx;
      			continue;
      		}
      		for(int j=1;j<=edge[from[x]].numval;j++){
      			for(int k=1;k<=edge[from[y]].numval;k++){
      				for(int l=1;l<=edge[las[x]].numval;l++){
      					for(int r=1;r<=edge[las[y]].numval;r++){
      						mx=max(mx,f[x][j][l]+f[y][k][r]-(edge[from[x]].val[j]==edge[from[y]].val[k]));
      					}
      				}
      			}
      		}
      		ans[has[u][i]]=mx;
      	}
      //	for(int i=1;i<=tp;i++)cout<<sta[i]<<" ";
      //	cout<<endl;
      	for(int i=1;i<=tp;i++){
      		for(int j=1;j<=3;j++){
      			for(int k=1;k<=3;k++){
      //				if(u==4)cout<<sta[i]<<" "<<edge[from[sta[i]]].val[j]<<" "<<edge[las[sta[i]]].val[k]<<" "<<f[sta[i]][j][k]<<endl;
      				f[sta[i]][j][k]=0;
      			}
      		}
      	}
      	return ;
      }
      void solve(int u){
      //	cout<<" "<<u<<endl;
      	del[u]=true;
      	calc(u);
      	for(int i=hd[u];i;i=edge[i].nxt){
      		int v=edge[i].to;
      		if(del[v])continue;
      		rt=0;
      		maxx[rt]=sum=siz[v];
      		dfs_w(v,u);
      		solve(rt);
      	}
      	return ;
      }
      void solve0(int u){
      //	cout<<u<<endl;
      	del[u]=true;
      //	calc(u);
      	for(int i=hd[u];i;i=edge[i].nxt){
      		int v=edge[i].to;
      		if(del[v])continue;
      		rt=0;
      		maxx[rt]=sum=siz[v];
      		dfs_w(v,u);
      		fa1[rt]=u;
      		dep[rt]=dep[u]+1;
      		solve0(rt);
      	}
      	return ;
      }
      int lca(int x,int y){
      	if(dep[x]<dep[y])swap(x,y);
      	while(dep[x]!=dep[y]){
      		x=fa1[x];
      	}
      	while(x!=y){
      		x=fa1[x];
      		y=fa1[y];
      	}
      	return x;
      }
      int main(){
      //	freopen("c0_1.in","r",stdin);
      	n=read();
      	m=read();
      //	memset(f,-1,sizeof f);
      	for(int i=1;i<=m;i++){
      		x=read();
      		y=read();
      		w=read();
      		if(mp.find(make_pair(x,y))==mp.end())mp[make_pair(x,y)]=mp[make_pair(y,x)]=cnt+1,add(x,y,w),add(y,x,w);
      		else{
      			int id=mp[make_pair(x,y)];
      			if(edge[id].numval<=2&&edge[id].val[1]!=w&&edge[id].val[2]!=w){
      				edge[id].val[++edge[id].numval]=w;
      			}
      			id++;
      			if(edge[id].numval<=2&&edge[id].val[1]!=w&&edge[id].val[2]!=w){
      				edge[id].val[++edge[id].numval]=w;
      			}
      		}
      	}
      //	for(int i=1;i<=cnt;i+=2){
      //		cout<<edge[i].to<<" "<<edge[i+1].to<<" "<<edge[i].val[1]<<" "<<edge[i].val[2]<<" "<<edge[i].val[3]<<endl;
      //	}
      	maxx[rt]=sum=n;
      	dfs_w(1,0);
      //	cout<<"ppp "<<rt<<endl;
      	solve0(rt);
      //	for(int i=1;i<=n;i++){
      //		cout<<fa1[i]<<" ";
      //	}
      	q=read();
      	for(int i=1;i<=q;i++){
      		xx[i]=read();
      		yy[i]=read();
      //		cout<<"  "<<lca(xx[i],yy[i])<<endl;
      		has[lca(xx[i],yy[i])].push_back(make_pair(xx[i],yy[i]));
      	}
      	memset(del,0,sizeof del);
      	memset(maxx,0,sizeof maxx);
      	memset(siz,0,sizeof siz);
      	rt=0;
      //	cout<<"hhh"<<endl;
      	maxx[rt]=sum=n;
      	dfs_w(1,0);
      	solve(rt);
      	for(int i=1;i<=q;i++){
      		printf("%d\n",ans[make_pair(xx[i],yy[i])]);
      	}
      	return 0;
      }
      

      \(\color{white}{\mathbb{不是花中偏愛菊,此花開盡更無花。}}\)

      posted @ 2021-08-14 17:10  y_cx  閱讀(78)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 99久久国产福利自产拍| 免费专区丝袜调教视频| 日本精品一区二区不卡| 中国亚州女人69内射少妇| 国产精品剧情亚洲二区| 国产无遮挡又黄又爽高潮| 加勒比无码人妻东京热| 国产三级国产精品久久成人| 日本久久精品一区二区三区| 精品久久久久久中文字幕| 熟女女同亚洲女同中文字幕| 国产成人综合久久亚洲av| 在线中文字幕第一页| 国产免费一区二区不卡| 人妻少妇一区二区三区| 高清中文字幕国产精品| 国产乱色国产精品免费视频| 亚洲精品国产中文字幕| 九九久久自然熟的香蕉图片| 亚洲欧美综合中文| 国产成人无码aa片免费看| 亚洲综合无码一区二区三区不卡| 91精品国产自产91精品| 人人爽人人爽人人片av东京热 | 亚洲欧洲日韩国内精品| 性视频一区| 视频一区二区不中文字幕| av高清无码 在线播放| 成人无套少萝内射中出| 亚洲一二三区精品美妇| 少妇激情一区二区三区视频小说 | 国产成人av一区二区三| 99久久成人国产精品免费| 欧美大胆老熟妇乱子伦视频| 亚洲AV无码破坏版在线观看| 99e久热只有精品8在线直播| 无码日韩精品一区二区三区免费| 激情综合网激情综合| 国产精品自在线拍国产| 国产精品有码在线观看| 日本人妻巨大乳挤奶水免费|