noip模拟15
A. 夜莺与玫瑰
分类讨论\(a\)和\(\dfrac{n}{2}\)、\(b\)和\(\dfrac{m}{2}\)的关系..
然后得到式子:
\[\Sigma_{a=1}^{n-1} \Sigma_{b=1}^{m-1}[gcd(a,b)==1)]((n-a)(m-b)-max(n-2*a,0)*max(m-2*b,0))
\]
于是前缀和优化即可..
B. 影子
我们可以从小规模向大规模转移..
维护每个并查集内的权值最大的链,然后考虑这个并查集向四周扩展即可..
B_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define re register ll
#define lf double
#define mp make_pair
const ll N=1e5+50;
inline void read(ll &ss)
{
ss=0; bool cit=0; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
if(cit) ss=-ss;
}
// 注意清零
ll alls,ts,n,cnt,ans;
bool vis[N];
ll value[N],head[N],son[N],top[N],siz[N],id[N],rk[N],path[N],fa[N],dep[N],father[N];
struct I { ll u,v,w,nxt; } a[N*2];
struct II { ll num,dad,val; } pot[N];
struct III { ll p1,p2,len; } S[N];
ll find(ll x) { return x==father[x] ? x : (father[x]=find(father[x])) ; }
bool comp(II aa,II bb) { return aa.val==bb.val ? aa.num<bb.num : aa.val>=bb.val ; }
void add(ll u,ll v,ll w)
{
a[++ts].u=u; a[ts].v=v; a[ts].w=w;
a[ts].nxt=head[u]; head[u]=ts;
}
void dfs1(ll now,ll dad,ll depth)
{
fa[now]=dad; dep[now]=depth;
siz[now]=1;
for(re i=head[now];i;i=a[i].nxt)
{
if(a[i].v==dad) continue;
path[a[i].v]=a[i].w+path[now];
dfs1(a[i].v,now,depth+1);
siz[now]+=siz[a[i].v];
if(siz[a[i].v]>siz[son[now]]) son[now]=a[i].v;
}
return ;
}
void dfs2(ll now,ll high)
{
top[now]=high;
id[now]=++cnt; rk[cnt]=now;
if(!son[now]) return ;
dfs2(son[now],high);
for(re i=head[now];i;i=a[i].nxt)
{
if(a[i].v==fa[now] or a[i].v==son[now]) continue;
dfs2(a[i].v,a[i].v);
}
return ;
}
ll lca(ll x,ll y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y] ? x : y ;
}
void work(ll now)
{
vis[now]=1; S[now].p1=S[now].p2=now;
ll l1,l2,r1,r2,dad,dis; father[now]=now;
for(re i=head[now];i;i=a[i].nxt)
{
if(vis[a[i].v])
{
father[now]=find(father[now]); father[a[i].v]=find(father[a[i].v]);
if(father[now]==father[a[i].v]) continue; // 目测没有什么用的一句话..
l1=S[father[now]].p1,l2=S[father[now]].p2;
r1=S[father[a[i].v]].p1,r2=S[father[a[i].v]].p2;
if(S[father[now]].len>S[father[a[i].v]].len)
S[father[a[i].v]].p1=l1,S[father[a[i].v]].p2=l2,S[father[a[i].v]].len=S[father[now]].len;
father[father[now]]=father[a[i].v]; father[now]=find(father[now]);
dad=lca(l1,r1); dis=path[l1]+path[r1]-path[dad]*2;
if(dis>S[father[now]].len)
S[father[now]].len=dis,S[father[now]].p1=l1,S[father[now]].p2=r1;
dad=lca(l1,r2); dis=path[l1]+path[r2]-path[dad]*2;
if(dis>S[father[now]].len)
S[father[now]].len=dis,S[father[now]].p1=l1,S[father[now]].p2=r2;
dad=lca(l2,r1); dis=path[l2]+path[r1]-path[dad]*2;
if(dis>S[father[now]].len)
S[father[now]].len=dis,S[father[now]].p1=l2,S[father[now]].p2=r1;
dad=lca(l2,r2); dis=path[l2]+path[r2]-path[dad]*2;
if(dis>S[father[now]].len)
S[father[now]].len=dis,S[father[now]].p1=l2,S[father[now]].p2=r2;
}
// cout<<"len:"<<S[father[now]].len<<" "<<value[now]<<" \n";
ans=max(ans,S[father[now]].len*value[now]);
}
return ;
}
signed main()
{
// freopen("0.in","r",stdin);
// freopen("out","w",stdout);
#define fill(x) memset(x,0,sizeof x);
read(alls);
while(alls--)
{
fill(vis); fill(value); fill(head); fill(son); fill(top); fill(siz); fill(id); fill(rk);
fill(path); fill(fa); fill(dep); fill(father);
read(n); ll u,v,w;
for(re i=1;i<=n;i++) { read(value[i]); pot[i].num=i; pot[i].dad=i; pot[i].val=value[i]; }
for(re i=1;i<=n-1;i++) { read(u); read(v); read(w); add(u,v,w); add(v,u,w); }
dfs1(1,0,1); dfs2(1,1); sort(pot+1,pot+1+n,comp);
for(re i=1;i<=n;i++) work(pot[i].num);
printf("%lld\n",ans);
for(ll i=1;i<=n;i++) pot[i].num=pot[i].dad=pot[i].val=0;
for(ll i=1;i<=ts;i++) a[i].u=a[i].v=a[i].w=a[i].nxt=0;
for(ll i=1;i<=n;i++) S[i].p1=S[i].p2=S[i].len=0;
ans=0,ts=0,cnt=0;
}
return 0;
}
/*
1 3
1 2 3
1 2 1
1 3 2
*/
C. 玫瑰花精
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll int
#define ull unsigned ll
#define re register ll
#define lf double
#define lb lower_bound
#define ub upper_bound
#define mp make_pair
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x);
#define Copy(x,y) memcpy(x,y,sizeof x);
inline ll read()
{
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=2e5+50;
ll n,m;
ll pos[N*5];
struct I { ll lx,rx,len,lp,rp,lc,rc; } tr[N*20];
// lx 和左边结合的长度,rx 和右边结合的长度,len 中间的最优解长度
// lp 和左边结合的端点,rp 和右边结合的端点,lc 中间最优解的左端点,rc 中间最优解的右端点
inline void pushup(ll x,ll l,ll r){
ll mid=(l+r)>>1;
tr[x].lx=tr[x<<1].lx,tr[x].lp=tr[x<<1].lp;
if(tr[x].lp==mid) tr[x].lx+=tr[x<<1|1].lx,tr[x].lp=tr[x<<1|1].lp;
tr[x].rx=tr[x<<1|1].rx,tr[x].rp=tr[x<<1|1].rp;
if(tr[x].rp==mid+1) tr[x].rx+=tr[x<<1].rx,tr[x].rp=tr[x<<1].rp;
tr[x].len=tr[x<<1].rx+tr[x<<1|1].lx,tr[x].lc=tr[x<<1].rp,tr[x].rc=tr[x<<1|1].lp;
if( ((tr[x].len+1)>>1) <= ((tr[x<<1].len+1)>>1) )
tr[x].len=tr[x<<1].len,tr[x].lc=tr[x<<1].lc,tr[x].rc=tr[x<<1].rc;
if( ((tr[x].len+1)>>1) < ((tr[x<<1|1].len+1)>>1) )
tr[x].len=tr[x<<1|1].len,tr[x].lc=tr[x<<1|1].lc,tr[x].rc=tr[x<<1|1].rc;
}
void update(ll x,ll l,ll r,ll pos,ll w){
if(l==r){
if(w&1){
tr[x].lx=0,tr[x].rx=0,tr[x].len=0,
tr[x].rp=pos+1,tr[x].lp=pos-1,tr[x].lc=pos+1,tr[x].rc=pos-1;
}
else{
tr[x].lx=1,tr[x].rx=1,tr[x].len=1,
tr[x].lp=pos,tr[x].rp=pos,tr[x].lc=pos,tr[x].rc=pos;
}
return ;
}
ll mid=(l+r)>>1;
if(pos<=mid) update(x<<1,l,mid,pos,w);
else update(x<<1|1,mid+1,r,pos,w);
pushup(x,l,r);
}
void build(ll x,ll l,ll r){
tr[x].lx=r-l+1,tr[x].rx=r-l+1,tr[x].len=r-l+1,
tr[x].lp=r,tr[x].rp=l,tr[x].lc=l,tr[x].rc=r;
if(l==r) return ;
ll mid=(l+r)>>1;
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
}
signed main()
{
n=read(),m=read(),build(1,1,n);
ll temp,dis1,dis2,dis,opt,id;
for(re i=1;i<=m;i++){
opt=read(),id=read();
if(opt&1){
if(tr[1].lc==1 or tr[1].lx>=((tr[1].len+1)>>1)) pos[id]=1;
else if(tr[1].rc==n or tr[1].rx>((tr[1].len+1)>>1)) pos[id]=n;
else pos[id]=(tr[1].lc+tr[1].rc)>>1;
update(1,1,n,pos[id],1); printf("%d\n",pos[id]);
}
else update(1,1,n,pos[id],2);
}
exit(0);
}

浙公网安备 33010602011771号