圓上均勻分布n 個點 然後 在這n個點中連n-3條邊 且這些邊不相交 有q次詢問每次詢問兩點間的最短距離
因為原圖是平面圖所以可以考慮轉成對偶圖 然後點分治
不想寫對偶圖&點分治可以考慮邊分治
每次選擇一條邊 將這條邊左右的邊的數量盡量平均分布
因為這題比較特殊是在乙個圓環上 所以考慮 我給所有點標號 然後列舉所有點的連得邊檢查這兩個標號相差的距離取最小的那條邊即可 然後每次針對這兩個點bfs一下 如果詢問的兩個點分在邊的兩邊 那麼直接統計答案否則去兩邊分治
#include
#include
#include
#include
#define n 110000
#define inf 0x3f3f3f3f
using
namespace
std;
inline
char gc()
return *s++;
}inline
int read()
while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
return x*f;
}vector
eg[n];
struct node;
int n,cnt,dis[n][2],id[n],start,ans[n];
bool flag[n*22][2];
inline
void bfs1(int x,int ii)
}}inline
void solve(const
vector
&g,const
vector
&q)start=cnt+1;int st,ed,mn=inf;
for (int i=0;ifor (int owo=0;owoint x=g[owo];
for (int i=0;iint y=eg[x][i];if (id[y]>cnt||id[y]continue;
int x1=x,y1=y;if (id[x1]>id[y1]) swap(x1,y1);
int mx=max(id[y1]-id[x1]+1,cnt-id[y1]+1+id[x1]-start+1);
if (mx0);bfs1(ed,1);vector
g1,g2;vector
q1,q2;
for (int i=0;iint x=q[i].x,y=q[i].y,idx=q[i].id,blx,bly;
if (id[x]>=id[st]&&id[x]<=id[ed]) blx=1;else blx=2;
if (id[y]>=id[st]&&id[y]<=id[ed]) bly=1;else bly=2;
if(blx==bly)
ans[idx]=min(dis[x][0]+dis[y][0],dis[x][1]+dis[y][1]);
}for (int i=id[st]-start;i<=id[ed]-start;++i) g1.push_back(g[i]);
for (int i=0;i<=id[st]-start;++i) g2.push_back(g[i]);
for (int i=id[ed]-start;iint main()
for (int i=0;i1;++i) eg[i].push_back(i+1),eg[i+1].push_back(i);
eg[n-1].push_back(0);eg[0].push_back(n-1);int m=read();g.reserve(n);q.reserve(m);
for (int i=0;ifor (int i=1;i<=m;++i));
}solve(g,q);
for (int i=1;i<=m;++i) printf("%d\n",ans[i]);
return
0;}
BJ 集訓測試13 鋼琴
題意給乙個序列 1e6 給乙個字符集大小為n且 100 每次1 n的概率生成其中乙個字元 求每個字首生成的期望 公式 dp i dp next i n i 證明 include define rep i,x,y for register int i x i y i define repd i,x,y...
BJ 集訓測試12 coin
題意 有n種貨幣,每種貨幣有乙個價值vi,並且滿足任意兩種貨幣的價值成倍數關係。即對於第i種貨幣和第j種貨幣,有vi整除vj,或者vj整除vi。現在給出這n種貨幣的價值,請你計算有多少種方案能湊出價值為m的貨幣組合。假設每種貨幣的數量是無限的,貨幣的價值互不相同。為了保證有解,我們約定存在一種貨幣的...
BJ 集訓測試13 平行
二維直角座標系中有n個點,它們的橫 縱座標的絕對值都不超過10。一次操作,你可以選擇某3個不共線的點a b c。然後以ab為對角線 c為另一頂點繪製平行四邊形abcd,然後用點d替換點c 即刪去點c保留點a b d 則d是確定並且唯一的。最初,n個點的座標互不相同。操作過程中這些點的座標可以重合。但...