123789456ye

已AFO

JSOI2010~2011

A 旅行

题面:bzoj
题解:\(dp\)
先按长度把边排序
指定必须走前\(l\)条边,枚举\(l\)
\(dis[i][j][k]\)表示当前到了\(i\)节点,已走过了\(j\)条前\(l\)条边,用了\(k\)次交换次数
code

B 找零钱的洁癖

题面:bzoj
题解:乱搞
首先直接bfs,搜索到一定程度break(卡时)
其次乱贪心(面向数据编程)
\(\text{M}\)\(\color{red}{\text{_sea}}\)说正解是整数规划?
不会,告辞
code

D 挖宝藏

题面:bzoj
题解:\(dp\)
要挖每个点等价于往上挖一个三角形
所以先把这个三角形上面两端点算出来,按先右端点递增再左端点递增排序
\(dp[i]\)表示前\(i\)个宝藏中强制选第\(i\)个时的最大收益
如果\(i\)\(j\)没有交集,则直接转移
否则暴力算出重复部分,减掉这部分贡献
code

F 排名

题面:bzoj
题解:拓扑排序
建一个大根堆
第一问在反图上跑,第二问在正图上跑拓扑排序
(为什么第一问在正图上跑小根堆是错的啊)
codeF

H 柠檬

题面:Luogu
题解:斜率优化
首先有一个显然的性质就是:一段两端必定相同并且是这一段选定的大小(否则可以证明结果必定小于这种)
\(dp[i]\)表示前\(i\)个的答案,\(s[i]\)表示\(i\)\(1\sim n\)内相同大小的第几个

\[dp[i]=max_{0<j\leq i}^{a[i]==a[j]}{\{dp[j-1]+a[i]*(s[i]-s[j]+1)^2\}} \]

于是有
只与\(i\)有关的:\(a[i]*s[i]^2+2*a[i]*s[i]+a[i]\)
只与\(j\)有关的:\(dp[j-1]+a[i]*s[j]^2-2*a[i]*s[j](a[i]==a[j])\)
既和\(i\)有关又和\(j\)有关的:\(-2a[i]s[i]s[j]\)
于是套斜率优化板子,维护上凸壳,栈顶最优决策
注意要先把自己丢进去再决策
由于空间问题用\(vector\)模拟栈
code

I 分特产

题面:Luogu
题解:容斥
设至少\(x\)个人什么都没有
也就是把\(a[i]\)个特产分给\(n-x\)个人
于是在\(n-x-1\)个空格里随意插\(a[i]\)块隔板
根据乘法原理,对每一种特产考虑最后再乘起来
方案数就是\(\prod_{i=1}^{m}{C_{n-x-1+a[i]}^{a[i]}}\)
容斥一下
答案就是恰好0人什么都没有

\[ans=\sum_{i=0}^{n-1}{(-1)^iC_{n}^{i}\prod_{j=1}^{m}{C_{n-i-1+a[j]}^{a[j]}}} \]

code

J 棒棒糖

题面:Luogu
是重题
题解:主席树
建一颗主席树,如果\([1,mid]\)内没有这么多个数字就显然没有,再看\([mid+1,r]\)
code

K 任务调度

题面:bzoj
题解:可并堆(左偏树)
修改操作就把这个点抠出来(合并它的左右儿子),再塞回去
据说可以用\(\text{pb_ds}\)水过去(然而我搞了一下午没搞出来)
code


A code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 155
struct Edge
{
	int fr,to,val;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to,int val)
{
	eg[++edgenum]=(Edge){head[fr],to,val};
	head[fr]=edgenum;
}
struct Road
{
	int l,r,val;
	inline friend bool operator < (Road a,Road b)
		{
			return a.val<b.val;
		}
}d[maxn];
struct Node
{
	int x,y,z,dis;
	inline friend bool operator < (Node a,Node b)
		{
			return a.dis>b.dis;
		}
};
priority_queue<Node> q;
int dis[52][maxn][maxn],vis[52][maxn][maxn];
int n,m,k,ans=0x7fffffff;
inline void work(int l)
{
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	dis[1][0][0]=0;
	q.push((Node){1,0,0});
	int x,y,z;
	while(!q.empty())
	{
		x=q.top().x,y=q.top().y,z=q.top().z;
		q.pop();
		if(vis[x][y][z]) continue;
		vis[x][y][z]=1;
		for(int i=head[x];i;i=eg[i].fr)
		{
#define to eg[i].to
			if(i<=(l<<1))
			{
				if(y<l&&dis[to][y+1][z]>dis[x][y][z]+d[y+1].val)
					dis[to][y+1][z]=dis[x][y][z]+d[y+1].val,q.push((Node){to,y+1,z,dis[to][y+1][z]});
			}
			else
			{
				if(y<l&&z<k&&dis[to][y+1][z+1]>dis[x][y][z]+d[y+1].val)
					dis[to][y+1][z+1]=dis[x][y][z]+d[y+1].val,q.push((Node){to,y+1,z+1,dis[to][y+1][z+1]});
				if(dis[to][y][z]>dis[x][y][z]+eg[i].val)
					dis[to][y][z]=dis[x][y][z]+eg[i].val,q.push((Node){to,y,z,dis[to][y][z]});
			}
#undef to
		}
	}
	for(int i=0;i<=k;++i) ans=min(ans,dis[n][l][i]);
}
int main()
{
	read(n),read(m),read(k);
	for(int i=1;i<=m;++i) read(d[i].l),read(d[i].r),read(d[i].val);
	sort(d+1,d+m+1);
	for(int i=1;i<=m;++i) add(d[i].l,d[i].r,d[i].val),add(d[i].r,d[i].l,d[i].val);
	for(int i=0;i<=m;++i) work(i);
	printf("%d\n",ans);
	return 0;
}

top

B code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pa pair<ll,ll>
#define mp make_pair
#define inf 0x7fffffff
queue<pa> q;
//unordered_map<ll,bool> m;
map<ll,bool> m;
ll n,a[105],x;
inline ll bfs()
{
    q.push(mp(0,0));
    ll val,step,tp;
    while(!q.empty())
    {
        val=q.front().first,step=q.front().second;
        q.pop();
        for(int i=1;i<=n;++i)
        {
            if(q.size()>=1000000) return inf;
            val<=x?tp=val+a[i]:tp=val-a[i];
            if(tp==x) return step+1;
            if(m[tp]) continue;
            m[tp]=1;
            q.push(mp(tp,step+1));
        }
    }
    return inf;
}
inline ll greedy()
{
    ll step=0,sum=x;
    for(int i=n;i;--i)
    {
        if(!a[i]) continue;
        step+=sum/a[i];
        sum-=sum/a[i]*a[i];
    }
    return sum?inf:step;
}
 
 
int main()
{
    //freopen("test.in","r",stdin);
    scanf("%lld",&x);
    if(!x) puts("0");
    while(scanf("%lld",&a[++n])!=EOF);
    sort(a+1,a+n+1);
    printf("%lld\n",min(bfs(),greedy()));
    return 0;
}

top

D code

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

inline void read(int& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
#define maxn 1005
inline int calc(int l,int r)
{
	return (r-l+2)*(r-l+2)>>2;
}
int n,dp[maxn];
struct Tr
{
	int l,r,p,p2,cost;
	inline friend bool operator < (Tr a,Tr b)
		{
			return a.r==b.r?a.l<b.l:a.r<b.r;
		}
}tr[maxn];
int main()
{
	read(n);
	int x,y;
	for(int i=1;i<=n;++i)
		read(x),read(y),read(tr[i].p),tr[i].l=x+y+1,tr[i].r=x-y-1,tr[i].cost=y*y;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			if(tr[i].l<=tr[j].l&&tr[i].r>=tr[j].r)
				tr[i].p2+=tr[j].p;
	sort(tr+1,tr+n+1);
	int nxt,sum,tmp;
	for(int i=1;i<=n;++i)
	{
		dp[i]=tmp=tr[i].p2-tr[i].cost;
		nxt=1,sum=0;
		for(int j=1;j<i;++j)
		{
			if(tr[j].r<tr[i].l) dp[i]=max(dp[i],dp[j]+tmp);
			if(tr[j].l<tr[i].l&&tr[i].l<=tr[j].r)
			{
				while(nxt<=i&&tr[nxt].r<=tr[j].r)
				{
					if(tr[nxt].l>=tr[i].l) sum+=tr[nxt].p;
					++nxt;
				}
				dp[i]=max(dp[i],dp[j]+tmp-(sum-calc(tr[i].l,tr[j].r)));
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;++i) ans=max(ans,dp[i]);
	printf("%d\n",ans);
	return 0;
}

top

F code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
struct Edge
{
	int fr,to;
}eg[maxn<<1],eg_rev[maxn<<1];
int head[maxn],head_rev[maxn],edgenum;
inline void add(int fr,int to)
{
	eg[++edgenum]=(Edge){head[fr],to};
	eg_rev[edgenum]=(Edge){head_rev[to],fr};
	head[fr]=head_rev[to]=edgenum;
}
int a,h[maxn],x[maxn],deg[maxn],deg_rev[maxn],n,cnt;
priority_queue<int> q;
void solve1()
{
	while(!q.empty()) q.pop();
	for(int i=1;i<=n;++i)
		if(!deg_rev[i]) q.push(i);
	while(!q.empty())
	{
		int id=q.top();q.pop();
		h[id]=cnt--;
		for(int i=head_rev[id];i;i=eg_rev[i].fr)
			if(!--deg_rev[eg_rev[i].to]) q.push(eg_rev[i].to);
	}
}
void solve2()
{
	while(!q.empty()) q.pop();
	for(int i=1;i<=n;++i)
		if(!deg[i]) q.push(i);
	while(!q.empty())
	{
		int id=q.top();q.pop();
		x[id]=++cnt;
		for(int i=head[id];i;i=eg[i].fr)
			if(!--deg[eg[i].to]) q.push(eg[i].to);
	}
}
int main()
{
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(a);
		if(a) add(a,i),++deg[i],++deg_rev[a];
	}
	cnt=n;solve1();
	cnt=0;solve2();
	for(int i=1;i<=n;++i) printf("%d ",h[i]);
	puts(" ");
	for(int i=1;i<=n;++i) printf("%d ",x[i]);
	puts(" ");
	return 0;
}

top

H code

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline void read(int& x)
{
	x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
#define maxn 100005
#define maxm 10005
#define ll long long
int las[maxm];
vector<int> st[maxm];
int a[maxn], s[maxn], n;
ll dp[maxn];
inline int x(const int& i)
{
	return a[i] * s[i];
}
inline int y(const int& i)
{
	return dp[i - 1] + (a[i] * s[i] - 2) * s[i];
}
inline ll Pow(const int& X)
{
	return 1ll * X * X;
}
inline double slope(int i, int j)
{
	return 1.0 * (y(i) - y(j)) / (x(i) - x(j));
}
inline ll calc(int i, int j)
{
	return dp[j - 1] + a[i] * Pow(s[i] - s[j] + 1);
}
signed main()
{
	read(n);
	for (int i = 1; i <= n; ++i)
		read(a[i]), s[i] = s[las[a[i]]] + 1, las[a[i]] = i;
	for (int i = 1; i <= n; ++i)
	{
#define t a[i]
#define A st[t][st[t].size()-2]
#define B st[t][st[t].size()-1]
		while (st[t].size() >= 2 && slope(A, i) >= slope(A, B)) st[t].pop_back();
		st[t].push_back(i);
		while (st[t].size() >= 2 && calc(i, A) >= calc(i, B)) st[t].pop_back();
		dp[i] = calc(i, st[t].back());
	}
	printf("%lld\n", dp[n]);
	return 0;
}

top

I code

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
	x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
#define p 1000000007
#define maxn 2005
int fac[maxn], inv[maxn], f[maxn], a[maxn];
inline int qpow(int x, int y)
{
	int ans = 1;
	while (y)
	{
		if (y & 1) ans = 1ll * ans * x % p;
		x = 1ll * x * x % p;
		y >>= 1;
	}
	return ans;
}
inline int C(int n, int m)
{
	return 1ll * fac[n] * inv[m] % p * inv[n - m] % p;
}

int main()
{
	int ans = 0, n, m;
	read(n), read(m);
	for (int i = 1; i <= m; ++i) read(a[i]);
	fac[0] = inv[0] = 1;
	for (int i = 1; i <= 2000; ++i) fac[i] = 1ll * i * fac[i - 1] % p;
	inv[2000] = qpow(fac[2000], p - 2);
	for (int i = 1999; i; --i) inv[i] = 1ll * inv[i + 1] * (i + 1) % p;
	for (int i = 0; i <
	<span id="codeI"></span>n; ++i)
	{
		f[0] = 1;
		for (int j = 1; j <= m; ++j) f[j] = 1ll * f[j - 1] * C(n - i - 1 + a[j], n - i - 1) % p;
		if (i & 1) ans = (ans - 1ll * f[m] * C(n, i) % p + p) % p;
		else ans = (ans + 1ll * f[m] * C(n, i) % p) % p;
	}
	printf("%d\n", ans);
	return 0;
}

top

J code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 500005
int ls[maxn*32],rs[maxn*32],val[maxn*32],rt[maxn],tot;
int n,m,w;
void build(int& rt,int l,int r)
{
	rt=++tot;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(ls[rt],l,mid);
	build(rs[rt],mid+1,r);
}
void update(int& rt,int las,int l,int r,int pos)
{
	rt=++tot;
	ls[rt]=ls[las],rs[rt]=rs[las],val[rt]=val[las]+1;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(pos<=mid) update(ls[rt],ls[las],l,mid,pos);
	else update(rs[rt],rs[las],mid+1,r,pos);
}
int query(int fr,int to,int len)
{
	int l=1,r=n,mid;
	while(true)
	{
		if(l==r) return l;
		mid=(l+r)>>1;
		if(((val[ls[to]]-val[ls[fr]])<<1)>len) r=mid,fr=ls[fr],to=ls[to];
		else if(((val[rs[to]]-val[rs[fr]])<<1)>len) l=mid+1,fr=rs[fr],to=rs[to];
		else return 0;
	}
}
int main()
{
	read(n),read(m);
	build(rt[0],1,n);
	for(int i=1;i<=n;++i)
		read(w),update(rt[i],rt[i-1],1,n,w);
	int l,r;
	for(int i=1;i<=m;++i)
		read(l),read(r),printf("%d\n",query(rt[l-1],rt[r],r-l+1));
	return 0;
}

top

K code

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 300005
int dis[maxn],rt[maxn],val[maxn],fa[maxn],son[maxn][2];
int merge(int x,int y)
{
    if(!x||!y) return x|y;
    if(val[x]>val[y]) swap(x,y);
    son[x][1]=merge(son[x][1],y);
    if(dis[son[x][0]]<dis[son[x][1]]) swap(son[x][0],son[x][1]);
    fa[son[x][0]]=fa[son[x][1]]=x;
    dis[x]=dis[son[x][1]]+1;
    return x;
}
void update(int x,int y,int v)
{
    int f=fa[y],tmp=merge(son[y][0],son[y][1]);
    if(rt[x]==y) rt[x]=tmp;
    else if(son[f][0]==y) son[f][0]=tmp;
    else son[f][1]=tmp;
    fa[tmp]=f;
    fa[y]=son[y][0]=son[y][1]=0;
    val[y]+=v;
    rt[x]=merge(rt[x],y);
}
 
int main()
{
    //freopen("test.in","r",stdin);
    int n,m,k;char op[10];
    read(n),read(m),read(k);
    int a,b,c;
    for(int i=1;i<=k;++i)
    {
        scanf("%s",op);
        read(a);
        if(op[0]=='A')
        {
            read(b),read(c);
            val[b]=c;
            rt[a]=merge(rt[a],b);
        }
        else if(op[0]=='D')
        {
            read(b),read(c);
            update(a,b,-c);
        }
        else if(op[0]=='T')
        {
            read(b);
            rt[b]=merge(rt[a],rt[b]);
            rt[a]=0;
        }
        else if(op[0]=='M')
            printf("%d\n",val[rt[a]]);
        else
        {
            read(b);
            if((son[rt[a]][0]&&val[son[rt[a]][0]]==val[rt[a]])||(son[rt[a]][1]&&val[son[rt[a]][1]]==val[rt[a]])) puts("ERROR");
            else update(a,rt[a],b);
        }
    }
    return 0;
}

top

posted @ 2020-02-01 22:30  123789456ye  阅读(161)  评论(0编辑  收藏  举报