1. 程式人生 > >USACO FEB18,Platinum

USACO FEB18,Platinum

slingshot

       題意:給定n個單向傳送門(a,b,c)和m次詢問(x,y),求至多用一次傳送門的最短路徑長度。

       即求min(|x-y|,min{|a-x|+|b-y|+c}),考慮分類討論後將絕對值開啟,用主席樹維護四個方向上對應的pa+qb+c(p,q為-1或1)的最小值即可。

AC程式碼如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define infll 1000000000000000000ll
#define N 100009
#define M 10000009
#define dn(x,y) (x>(y)?x=(y):0)
using namespace std;

int n,m,trtot,cnt,hsh[N],rt1[N],rt2[N],ls[M],rs[M];
struct node{ int x,y,z; }a[N];
bool cmpx(node u,node v){ return u.x<v.x; }
struct point{ ll x,y; }T[M];
void calc(point &u,point v){
	dn(u.x,v.x); dn(u.y,v.y);	
}
void ins(int &k,int p,int l,int r,int x,ll u,ll v){
	k=++trtot; T[k]=T[p]; calc(T[k],(point){u,v});
	if (l==r) return;
	int mid=l+r>>1;
	if (x<=mid){ rs[k]=rs[p]; ins(ls[k],ls[p],l,mid,x,u,v); }
	else{ ls[k]=ls[p]; ins(rs[k],rs[p],mid+1,r,x,u,v); }
}
point qry(int k,int l,int r,int x,int y){
	if (!k) return (point){infll,infll};
	if (x<=l && r<=y) return T[k];
	int mid=l+r>>1; point ans=(point){infll,infll};
	if (x<=mid) calc(ans,qry(ls[k],l,mid,x,y));
	if (y>mid) calc(ans,qry(rs[k],mid+1,r,x,y));
	return ans;
}
int main(){
	freopen("slingshot.in","r",stdin); freopen("slingshot.out","w",stdout);
	scanf("%d%d",&n,&m);
	int i,k,x,y;
	for (i=1; i<=n; i++){
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
		hsh[i]=a[i].x;
	}
	sort(hsh+1,hsh+n+1);
	cnt=unique(hsh+1,hsh+n+1)-hsh-1; hsh[++cnt]=inf+1;
	sort(a+1,a+n+1,cmpx);
	T[0].x=T[0].y=infll;
	for (i=1; i<=n; i++){
		k=lower_bound(hsh+1,hsh+cnt+1,a[i].x)-hsh;
		if (!rt1[k]) rt1[k]=rt1[k-1];
		ins(rt1[k],rt1[k],0,inf,a[i].y,a[i].z-a[i].x-a[i].y,a[i].z-a[i].x+a[i].y);
	}
	for (i=n; i; i--){
		k=lower_bound(hsh+1,hsh+cnt+1,a[i].x)-hsh;
		if (!rt2[k]) rt2[k]=rt2[k+1];
		ins(rt2[k],rt2[k],0,inf,a[i].y,a[i].z+a[i].x-a[i].y,(ll)a[i].z+a[i].x+a[i].y);
	}
	ll ans;
	while (m--){
		scanf("%d%d",&x,&y);
		ans=abs(y-x); k=lower_bound(hsh+1,hsh+cnt+1,x)-hsh;
		dn(ans,qry(rt2[k],0,inf,0,y).x-x+y);
		dn(ans,qry(rt2[k],0,inf,y,inf).y-x-y);
		dn(ans,qry(rt1[k-1],0,inf,0,y).x+x+y);
		dn(ans,qry(rt1[k-1],0,inf,y,inf).y+x-y);
		printf("%lld\n",ans);
	}
	return 0;
}

newbarn

       題意:支援合併和加點,多次詢問到某點距離最遠的點的距離。

       顯然距離最遠的點一定是直徑端點。考慮維護每個連通塊的直徑,合併的時候新的直徑兩端點一定是原來兩條直徑四個端點中的兩個。

AC程式碼如下:

#include<bits/stdc++.h>
#define N 100009
using namespace std;

int n,m,tot,fst[N],pnt[N<<1],nxt[N<<1],p[N][2],dad[N];
int a[N],fa[N],d[N],sz[N],anc[N],son[N];
bool vis[N]; char op[N][3];
void add(int x,int y){
	pnt[++tot]=y; nxt[tot]=fst[x]; fst[x]=tot;
}
void dfs(int x){
	int i,y; vis[x]=1; sz[x]=1;
	for (i=fst[x]; i; i=nxt[i]){
		y=pnt[i];
		if (y!=fa[x]){
			fa[y]=x; d[y]=d[x]+1;
			dfs(y); sz[x]+=sz[y];
			if (sz[y]>sz[son[x]]) son[x]=y;
		}
	}
}
void dvd(int x,int tp){
	int i,y; anc[x]=tp;
	if (son[x]) dvd(son[x],tp);
	for (i=fst[x]; i; i=nxt[i]){
		y=pnt[i];
		if (y!=fa[x] && y!=son[x]) dvd(y,y);
	}
}
int lca(int x,int y){
	for (; anc[x]!=anc[y]; x=fa[anc[x]])
		if (d[anc[x]]<d[anc[y]]) swap(x,y);
	return d[x]<d[y]?x:y;
}
int dist(int x,int y){ return d[x]+d[y]-(d[lca(x,y)]<<1); }
int getdad(int x){ return x==dad[x]?x:dad[x]=getdad(dad[x]); }
void mrg(int x,int y){
	int u=p[x][0],v=p[x][1],mx=dist(u,v),i,j,tmp;
	for (i=0; i<2; i++)
		for (j=0; j<2; j++)
			if ((tmp=dist(p[x][i],p[y][j]))>mx){
				mx=tmp; u=p[x][i]; v=p[y][j];
			}
	dad[x]=y;
	if (dist(p[y][0],p[y][1])>mx) return;
	p[y][0]=u; p[y][1]=v;
}
int main(){
	freopen("newbarn.in","r",stdin); freopen("newbarn.out","w",stdout);
	scanf("%d",&m);
	int i;
	for (i=1; i<=m; i++){
		scanf("%s",op[i]); scanf("%d",&a[i]);
		if (op[i][0]=='B'){
			n++;
			if (a[i]!=-1){
				add(n,a[i]); add(a[i],n);
			}
		}
	}
	for (i=1; i<=n; i++) if (!vis[i]){
		d[i]=1; dfs(i); dvd(i,i);
	}
	for (i=1; i<=n; i++){
		dad[i]=i; p[i][0]=p[i][1]=i;	
	}
	n=0;
	for (i=1; i<=m; i++) if (op[i][0]=='B'){
		n++;
		if (a[i]==-1) continue;
		if (getdad(n)==getdad(a[i])) continue;
		mrg(getdad(n),getdad(a[i]));
	} else
		printf("%d\n",max(dist(a[i],p[getdad(a[i])][0]),dist(a[i],p[getdad(a[i])][1])));
	return 0;
}

gymnasts

       題意:問有多少長度為N且每一個數<=N的陣列a,

                 滿足陣列b(b[i]=\sum_{j=0}^{n}[a[i-j]>j])和陣列a相同。

       首先令a[i]=a[i]-1。假設a中最大的數為a[k]=x,y=gcd(x,n),那麼可知a[k-y]=x,a[k-y+1]=x-1。進一步可以知道任意a[i]=a[i-y],且a[i]=x或x-1。列舉y然後簡單統計即可。

AC程式碼如下:

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;

int cnt,ans=1; ll n,p[19];
int ksm(int x,ll y){
	int z=1; for (; y; y>>=1,x=(ll)x*x%mod) if (y&1) z=(ll)z*x%mod;
	return z;
}
ll gcd(ll x,ll y){ return y?gcd(y,x%y):x; }
int calc(ll x){
	return ksm(2,x)-1;
	ll i; int ans=0;
	for (i=1; i<=x; i++) ans=(ans+ksm(2,gcd(x,i)))%mod;
	return (ll)ans*ksm(x,mod-2)%mod-1;
}
void solve(ll x){
	if (x==n) return;
	int i; ll y=n/x;
	for (i=1; i<=cnt; i++) if (!(y%p[i])) y=y/p[i]*(p[i]-1);
	//cerr<<x<<' '<<calc(x)<<' '<<y<<endl;
	ans=(ans+y%mod*calc(x))%mod;
}
int main(){
	freopen("gymnasts.in","r",stdin); freopen("gymnasts.out","w",stdout);
	scanf("%lld",&n);
	int i; ll x=n;
	for (i=2; (ll)i*i<=n; i++) if (!(x%i)){
		p[++cnt]=i;
		for (; !(x%i); x/=i);	
	}
	if (x>1) p[++cnt]=x;
	for (i=1; (ll)i*i<=n; i++) if (!(n%i)){
		solve(i);
		if (i!=n/i) solve(n/i);	
	}
	printf("%d\n",ans);
	return 0;
}

by lych

2018.2.28

相關推薦

USACO FEB18,Platinum

slingshot       題意:給定n個單向傳送門(a,b,c)和m次詢問(x,y),求至多用一次傳送門的最短路徑長度。       即求min(|x-y|,min{|a-x|+|b-y|+c}),考慮分類討論後將絕對值開啟,用主席樹維護四個方向上對應的pa+qb+c(

USACO 2017 Open Platinum

Description: 有一個nnn個點,mmm條邊的圖,每個點都有顏色,顏色種類的範圍為[1,K][1,K][1,K]。 現在有qqq個操作,每個操作將點xxx的顏色改為kkk,在每個操作後求不同顏色的最小距離。 n≤2⋅105,m≤4⋅105,K≤106,

USACO】2018 February Contest, Platinum題解

【比賽經歷】看完T1先寫了一個\(O(NM)\)的暴力,交一發,得分5/10,說明正確地理解了題意。感覺T1碼量挺大的,於是先放了一下。T2是傻題,看完10min寫掉了,得分10/10。回過頭來把T1的線段樹碼了,一遍寫對,不用痛苦地調這個鬼題,提交,得分10/10,跑了1.

USACO 2018 January Contest Platinum A: Lifeguards 題解

將所有的區間按左端點從小到大排序 我們處理那些被完全包含的區間,這些區間即使刪除也不會使答案變壞 這樣先刪一波,如果發現這種小區間的個數多於k,就可以直接算答案了 否則我們要dp 設dp[i][j]為考慮到第i個區間,已經刪除了j個區間,且第i個區間沒有被刪除的情況下最大的

USACO Section 2.1 Healthy Holsteins

int pop feed using health 位運算 div bool code /* ID: lucien23 PROG: holstein LANG: C++ */ #include <iostream> #include <fstre

cogs 142. [USACO Jan08] iCow播放器 ???

con open i+1 限制 清零 stream get 如果 etc ☆ 輸入文件:icow.in 輸出文件:icow.out 簡單對比 時間限制:1 s 內存限制:128 MB 被無止境的農活壓榨得筋疲力盡後,Farmer John打算用他在MP3

USACO 4.4.2 追查壞牛奶 oj1341 網絡流最小割問題

+= source dinic fread ati script str one color 描述 Description 你第一天接手三鹿牛奶公司就發生了一件倒黴的事情:公司不小心發送了一批有三聚氰胺的牛奶。很不幸,你發現這件事的時候,有三聚氰胺的牛奶已經進入了送貨網

最小生成樹基礎模板題(USACO Training Section 3.1 最短網絡 Agri-Net)

格式 聯網 std fin sync 輸出格式 class cti ons 農民約翰被選為他們鎮的鎮長!他其中一個競選承諾就是在鎮上建立起互聯網,並連接到所有的農場。當然,他需要你的幫助。 約翰已經給他的農場安排了一條高速的網絡線路,他想把這條線路共享給其他農場。為了用最

USACO Section 2.1 Ordered Fractions

fstream rime include utf pop red primes operation actions /* ID: lucien23 PROG: frac1 LANG: C++ */ #include <iostream> #include

USACO Section 1.3 : Calf Flac (calfflac)

pop name sizeof lib oid ring putc 空格 urn 題意:據說假設你給無限僅僅母牛和無限臺巨型便攜式電腦(有很大的鍵盤),那麽母牛們會制造出世上最優秀的回文。你的工作就是去尋找這些牛制造的奇觀(最優秀的回文)。 在尋找回文時不用理睬那些標點

1861 奶牛的數字遊戲 2006年USACO

她在 b-s wiki 展開 bold pri efault 過程 button codevs——1861 奶牛的數字遊戲 2006年USACO 時間限制: 1 s 空間限制: 128000 KB

USACO 6.5 Betsy's Tour (插頭dp)

tours print eve 出現 png lin per fine 麻煩 Betsy‘s TourDon Piele A square township has been divided up into N2 square plots (1 <= N <=

[usaco]醜數

truct open 如果 ++ i+1 hid pri names close 思考 首先產生的思路是,用小根堆的最小元素(top)來與 k個數 相乘,之後把結果再扔進小根堆,每次操作得到的即是第k小。 不過要註意一下判重。但是非常悲劇的是 在遇到極限數據的時候TLE了

USACO 5.1.1凸包

blog n) pre pos blank ace stdin href sqrt 轉自:http://blog.csdn.net/cnyali/article/details/50097593 程序: #include <iostream> #includ

USACO 6.5 The Clocks

turned design class called concat [] side mes con The ClocksIOI‘94 - Day 2 Consider nine clocks arranged in a 3x3 array thusly: |-------|

USACO Ordered Fractions

pri per class amp const rac bsp ++ name 首先看一下題目 Consider the set of all reduced fractions between 0 and 1 inclusive with denominators l

USACO Sorting a Three-Valued Sequence

ogr tin ace required sil lines nts 得到 expected 首先來看一下題目: Sorting is one of the most frequently performed computational tasks. Consider th

[COGS309] [USACO 3.2] 香甜的黃油

output sample while pen lov -1 輸入 inpu spf ★★ 輸入文件:butter.in 輸出文件:butter.out 簡單對比 時間限制:1 s 內存限制:128 MB 描述 農夫John發現做出全威

青銅蓮花池(Bronze Lilypad Pond, USACO 2007 Feb)

bsp 成了 scan pos main span 想去 分開 pop 題目描述 為了讓奶牛們娛樂和鍛煉,農夫約翰建造了一個美麗的池塘。這個長方形的池子被分成了 M 行 N 列個方格(1 ≤ M, N ≤ 30) 。一些格子是堅固得令人驚訝的蓮花,還有一些格子是巖石,其余的

[USACO]又買飼料 單調隊列dp

while str span iostream sam -i 商家 () i++ 題目描述 約翰開車回家,又準備順路買點飼料了(咦?為啥要說“又”字?)回家的路程一共有 E 公裏, 這一路上會經過 N 家商店,第 i 家店裏有 F i 噸飼料,售價為每噸 C i 元。約翰