123789456ye

已AFO

JSOI2015

JSOI2015

A salsman

题面:Luogu
题解:树形dp
考虑设\(dp[u]\)表示经过\(u\)及其子树的最大收益
停留次数就把子树的收益算一下排个序取前多少个就好了
第二问的话不是独自的有几种情况

  • 这颗子树的选了的和没选的有收益相同的
  • 有选了收益0的(也就是可选可不选)
  • 子树里有不是独自的
    分类讨论一下即可

code

D 子集选取

题面:Luogu
题解:
由手玩小样例可以得到\(ans=2^{nk}\)
显然对每个数可以分开计算
对于一个数,每一步都可以选或者不选,走k步,把选了的全部丢到最前面即可,方案数为\(2^k\)
因为每个数都可以选或者不选,所以总方案数\(2^{nk}\)
code

E 送礼物

题面:Luogu
题解:贪心+二分+单调队列
显然最大最小值应该是在两个端点处(长度不到L的就是滑动窗口,特判一下即可)
\(f(x)=x* mid-a[x]\)
式子可以化为\(f(j)-f(i)\geq k* mid\)
于是维护f的单调减的单调队列
然后把序列反过来再做一遍
deque被卡了
为什么手写deque加一个template就疯狂CE啊
code

F 字符串树

题面:Luogu
题解:可持久化Trie
路径查询就用两端点查询值减去lca的查询值就好了
code

G 非诚勿扰

题面:Luogu
题解:树状数组,概率
s个候选人中选了第x个的概率为
\begin{aligned}
ans &=p* [(1-p){x-1}+(1-p)+...] \newline
&=p* (1-p)^{x-1}* \frac{1-0}{1-(1-p)^s}
\end{aligned}
可以发现我们要求的东西是一个类似逆序对的东西,上树状数组搞一下即可
code

H 套娃

题面:Luogu
题解:贪心
把out扔到multiset里面,每个in与能放的最大的out匹配
证明可以看\(\text{M}\)\(\color{red}{\text{_sea}}\)博客
code

I 最小表示

题面:bzoj
题解:bitset 乱搞
考虑对于每条边\(u,v\)求出\(u\)能到的所有点和能到\(v\)的所有点,如果这两个有并集则这条边可以删掉
用拓扑排序求出能到某个点的所有点,再在反图上跑一遍即可
code

J 圈地

题面:Luogu
题解:最大流
S向一个人买的房连边,另一个人向T连边,边权为房价
墙壁之间互相连边
答案就是所有房子价格减去最小割
code

K 串分割

题面:Luogu
题解:后缀排序
贪心的想,各段长度必定相同或者有几个比其他的多1
先倍长原串,跑一边后缀排序
然后二分一个rk表示最大的那一段的rk,枚举第一次的分割点,
如果这一段的\(rk<=mid\)就直接把长的放上去,否则放长度减一的
如果最后总长度大于等于原长就符合要求了,\(r=mid\)
code

L 染色问题

题面:Luogu
题解:容斥
考虑\(i\)\(j\)列不涂,\(k\)种颜色不用,随意涂
则此时答案为

\[{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)} \]

其中\(c-k+1\)是因为还可以不涂
于是容斥一下

\[ans=\sum_{i=0}^{n}{\sum_{j=0}^{m}{\sum_{k=0}^{c}{(-1)^{i+j+k}{n\choose i}{m\choose j}{c\choose k}(c-k+1)^{(n-i)*(m-j)}}}} \]

code

M 最大公约数

题面:Luogu
题解:
有一个结论:序列的gcd个数是\(O(\log)\)
于是把r扫一遍,把所有gcd会改变的点扔到vector里面
不理解可以自己输出一下中间变量
code

A 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 100005
int n,val[maxn],s[maxn],dp[maxn],f[maxn];
struct Edge
{
	int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to)
{
	eg[++edgenum]=(Edge){head[fr],to};
	head[fr]=edgenum;
}
inline bool cmp(const int& x,const int& y)
{
	return dp[x]>dp[y];
}
vector<int> ve;

void dfs(int rt,int fa)
{
	dp[rt]=val[rt];
	for(int i=head[rt];i;i=eg[i].fr)
		if(eg[i].to!=fa) dfs(eg[i].to,rt);
	ve.clear();
	for(int i=head[rt];i;i=eg[i].fr)
		if(eg[i].to!=fa&&dp[eg[i].to]>=0) ve.push_back(eg[i].to);
	sort(ve.begin(),ve.end(),cmp);
	int lim=min(s[rt]-1,(int)ve.size());
	for(int i=0;i<lim;++i) dp[rt]+=dp[ve[i]],f[rt]|=f[ve[i]];
	if(lim&&!dp[ve[lim-1]]) f[rt]=1;
	if(lim<(int)ve.size()&&dp[ve[lim-1]]==dp[ve[lim]]) f[rt]=1;
}
int main()
{
	read(n);s[1]=n;
	for(int i=2;i<=n;++i) read(val[i]);
	for(int i=2;i<=n;++i) read(s[i]);
	int x,y;
	for(int i=1;i<n;++i) read(x),read(y),add(x,y),add(y,x);
	dfs(1,0);
	printf("%d\n",dp[1]);
	puts(f[1]?"solution is not unique":"solution is unique");
	return 0;
}

top

D code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define p 1000000007
inline ll qpow(ll x,ll y)
{
	ll ans=1;
	while(y)
	{
		if(y&1) ans=ans*x%p;
		x=x*x%p;
		y>>=1;
	}
	return ans;
}

int main()
{
	ll n,k;
	scanf("%lld%lld",&n,&k);
	printf("%lld\n",qpow(2,n*k%(p-1)));
	return 0;
}

top

codeE

#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 200005
const double eps = 1e-7;
int a[maxn], n, L, R, K;
struct Queue
{
	int head, tail;
	pair<double, int> val[maxn];
	void clear()
	{
		head = 1, tail = 0;
	}
	pair<double, int> back()
	{
		return val[tail];
	}
	pair<double, int> front()
	{
		return val[head];
	}
	void pop_back()
	{
		--tail;
	}
	void pop_front()
	{
		++head;
	}
	void push_back(pair<double, int> v)
	{
		val[++tail] = v;
	}
	bool empty()
	{
		return head > tail;
	}
}q;
double ans, l, r, mid, val[maxn];
inline double func(int x)
{
	return x * mid - a[x];
}
inline bool check()
{
	q.clear();
	for (int i = L; i <= n; ++i)
	{
		while (!q.empty() && q.front().second + R <= i) q.pop_front();
		int tp = i - L + 1;
		while (!q.empty() && q.back().first <= func(tp)) q.pop_back();
		q.push_back(make_pair(func(tp), tp));
		if (!q.empty() && q.front().first > func(i) + K * mid) return true;
	}
	return false;
}
inline void special()
{
	q.clear();
	q.push_back(make_pair(a[1], 1));
	for (int i = 2; i <= n; ++i)
	{
		while (!q.empty() && q.front().second + L <= i) q.pop_front();
		ans = max(ans, (a[i] - q.front().first) / (L - 1 + K));
		while (!q.empty() && q.back().first >= a[i]) q.pop_back();
		q.push_back(make_pair(a[i], i));
	}
}
inline void solve()
{
	l = 0, r = 1000;
	while (r - l > eps)
	{
		mid = (l + r) / 2;
		if (check()) l = mid;
		else r = mid;
	}
	ans = max(ans, l);
	special();
}
int main()
{
	int T; read(T);
	while (T--)
	{
		ans = 0;
		read(n), read(K), read(L), read(R);
		for (int i = 1; i <= n; ++i) read(a[i]);
		solve();
		reverse(a + 1, a + n + 1);
		solve();
		printf("%.4lf\n", ans);
	}
	return 0;
}

top

codeF

#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 100005
struct Edge
{
	int fr, to, id;
}eg[maxn << 1];
int head[maxn], edgenum;
inline void add(int fr, int to, int id)
{
	eg[++edgenum] = { head[fr],to,id };
	head[fr] = edgenum;
}
int s[maxn][12], len[maxn], fa[maxn][18], dep[maxn];
struct Node
{
	int son[26], num;
}t[maxn * 20];
int tot, root[maxn];
void insert(int& rt, int las, int pos, int* s, int len)
{
	rt = ++tot;
	t[rt] = t[las], ++t[rt].num;
	if (pos > len) return;
	insert(t[rt].son[s[pos]], t[rt].son[s[pos]], pos + 1, s, len);
}
void dfs(int rt)
{
	for (int i = head[rt]; i; i = eg[i].fr)
		if (eg[i].to != fa[rt][0])
		{
			fa[eg[i].to][0] = rt;
			dep[eg[i].to] = dep[rt] + 1;
			insert(root[eg[i].to], root[rt], 1, s[eg[i].id], len[eg[i].id]);
			dfs(eg[i].to);
		}
}
int lca(int x, int y)
{
	if (dep[x] < dep[y]) swap(x, y);
	int dist = dep[x] - dep[y];
	for (int i = 17; i >= 0; --i)
		if ((1 << i) & dist) x = fa[x][i];
	if (x == y) return x;
	for (int i = 17; i >= 0; --i)
		if (fa[x][i] != fa[y][i])
			x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}
inline int calc(int rt, int len)
{
	for (int i = 1; i <= len; ++i) rt = t[rt].son[s[0][i]];
	return t[rt].num;
}
char S[maxn];
int main()
{
	int n, m;
	read(n);
	for (int i = 1, u, v; i < n; ++i)
	{
		read(u), read(v), add(u, v, i), add(v, u, i);
		scanf("%s", S + 1);
		len[i] = strlen(S + 1);
		for (int j = 1; j <= len[i]; ++j) s[i][j] = S[j] - 'a';
	}
	dfs(1);
	for (int i = 1; i <= 17; ++i)
		for (int j = 1; j <= n; ++j)
			fa[j][i] = fa[fa[j][i - 1]][i - 1];
	read(m);
	for (int i = 1, u, v; i <= m; ++i)
	{
		read(u), read(v), scanf("%s", S + 1);
		int Lca = lca(u, v);
		len[0] = strlen(S + 1);
		for (int j = 1; j <= len[0]; ++j) s[0][j] = S[j] - 'a';
		printf("%d\n", calc(root[u], len[0]) + calc(root[v], len[0]) - (calc(root[Lca], len[0]) << 1));
	}
	return 0;
}

top

G code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& 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 lb long double
#define maxn 500005
lb c[maxn],p;
int n,m;
inline int lowbit(const int& x)
{
	return x&(-x);
}
inline void update(const int& pos,const lb& val)
{
	for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
}
inline lb query(const int& pos)
{
	lb ans=0;
	for(int i=pos;i;i-=lowbit(i)) ans+=c[i];
	return ans;
}
vector<int> ve[maxn];
int main()
{
	read(n),read(m);
	scanf("%Lf",&p);
	int x,y;
	lb ans=0,tp;
	register vector<int>::iterator it;
	register int i;
	for(i=1;i<=m;++i) read(x),read(y),ve[x].push_back(y);
	for(i=1;i<=n;++i) sort(ve[i].begin(),ve[i].end());
	for(i=1;i<=n;++i)
	{
		if(ve[i].empty()) continue;
		tp=p/(1-pow(1-p,ve[i].size()));
		for(it=ve[i].begin();it!=ve[i].end();++it,tp*=(1-p))
			ans+=tp*(query(n)-query(*it)),update(*it,tp);
	}
	printf("%.2Lf\n",ans);
	return 0;
}

top

H code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
int n;
struct Item
{
	int out,in,w;
	inline friend bool operator < (Item a,Item b)
		{
			return a.w>b.w;
		}
}it[maxn];
multiset<int> s;
multiset<int>::iterator tp;
int main()
{
	read(n);
	long long ans=0;
	for(int i=1;i<=n;++i)
		read(it[i].out),read(it[i].in),read(it[i].w),s.insert(it[i].out),ans+=1ll*it[i].w*it[i].in;
	sort(it+1,it+n+1);
	for(int i=1;i<=n;++i)
	{
		tp=s.lower_bound(it[i].in);
		if(tp!=s.begin()) ans-=1ll*(*--tp)*it[i].w,s.erase(tp);
	}
	printf("%lld\n",ans);
	return 0;
}

top

I code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 30005
int n,m,fr[maxn<<2],to[maxn<<2];
struct Graph
{
	struct Edge
	{
		int fr,to;
	}eg[maxn<<2];
	int deg[maxn],head[maxn],edgenum;
	bitset<maxn> bit[maxn];
	inline void add(int fr,int to)
		{
			eg[++edgenum]=(Edge){head[fr],to};
			head[fr]=edgenum;++deg[to];
		}
	void toposort()
		{
			queue<int> q;
			while(!q.empty()) q.pop();
			for(int i=1;i<=n;++i) if(!deg[i]) q.push(i);
			while(!q.empty())
			{
				int tp=q.front();q.pop();
				for(int i=head[tp];i;i=eg[i].fr)
				{
					bit[eg[i].to]|=bit[tp],bit[eg[i].to][tp]=1;
					if(!--deg[eg[i].to]) q.push(eg[i].to);
				}
			}
		}	
}G,G_rev;
int main()
{
	read(n),read(m);
	int ans=0;
	for(int i=1;i<=m;++i)
	{
		read(fr[i]),read(to[i]);
		G.add(fr[i],to[i]),G_rev.add(to[i],fr[i]);
	}
	G.toposort();G_rev.toposort();
	for(int i=1;i<=m;++i)
		if((G.bit[to[i]]&G_rev.bit[fr[i]]).any()) ++ans;
	printf("%d\n",ans);
	return 0;
}

top

codeJ

#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 64005
#define inf 0x3f3f3f3f
struct Edge
{
	int fr, to, val;
}eg[maxn << 3];
int head[maxn], edgenum = 1, n, m;
inline void add(int fr, int to, int val)
{
	eg[++edgenum] = { head[fr],to,val };
	head[fr] = edgenum;
}
inline void Add(int fr, int to, int val)
{
	add(fr, to, val), add(to, fr, 0);
}
int S, T, maxflow, dep[maxn], cur[maxn], vis[maxn];
queue<int> q;
bool bfs()
{
	for (int i = 1; i <= T; ++i) dep[i] = inf, cur[i] = head[i];
	q.push(S), dep[S] = 0;
	while (!q.empty())
	{
		int tp = q.front(); q.pop();
		for (int i = head[tp]; i; i = eg[i].fr)
			if (dep[eg[i].to] > dep[tp] + 1 && eg[i].val)
			{
				dep[eg[i].to] = dep[tp] + 1;
				if (!vis[eg[i].to]) vis[eg[i].to] = 1, q.push(eg[i].to);
			}
		vis[tp] = 0;
	}
	return dep[T] != inf;
}
int dfs(int rt, int flow)
{
	if (rt == T)
	{
		maxflow += flow;
		return flow;
	}
	int tmpflow, used = 0;
	for (int& i = cur[rt]; i; i = eg[i].fr)
	{
		if (dep[eg[i].to] == dep[rt] + 1 && eg[i].val)
			if (tmpflow = dfs(eg[i].to, min(flow - used, eg[i].val)))
			{
				used += tmpflow;
				eg[i].val -= tmpflow;
				eg[i ^ 1].val += tmpflow;
				if (used == flow) break;
			}
	}
	return used;
}
inline void dinic()
{
	while (bfs()) dfs(S, inf);
}
inline int id(int x, int y)
{
	return (x - 1) * n + y;
}
int main()
{
	read(n), read(m);
	S = n * m + 1, T = n * m + 2;
	int tp, ans = 0;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
		{
			read(tp);
			if (tp > 0) Add(S, id(i, j), tp), ans += tp;
			else Add(id(i, j), T, -tp), ans -= tp;
		}
	for (int i = 1; i < n; ++i)
		for (int j = 1; j <= m; ++j)
		{
			read(tp);
			Add(id(i, j), id(i + 1, j), tp);
			Add(id(i + 1, j), id(i, j), tp);
		}
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j < m; ++j)
		{
			read(tp);
			Add(id(i, j), id(i, j + 1), tp);
			Add(id(i, j + 1), id(i, j), tp);
		}
	dinic();
	printf("%d\n", ans - maxflow);
	return 0;
}

top

codeK

#include<bits/stdc++.h>
using namespace std;
#define maxn 400005
char s[maxn];
int buc[maxn], rk[maxn], sa[maxn], tp[maxn], height[maxn], n, m, k;
inline void Rsort()
{
	register int i;
	for (i = 0; i <= m; ++i) buc[i] = 0;
	for (i = 1; i <= n; ++i) ++buc[rk[tp[i]]];
	for (i = 1; i <= m; ++i) buc[i] += buc[i - 1];
	for (i = n; i; --i) sa[buc[rk[tp[i]]]--] = tp[i];
}
inline bool cmp(int* f, int x, int y, int k)
{
	return f[x] == f[y] && f[x + k] == f[y + k];
}
void Suffix()
{
	for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i;
	m = 127, Rsort();
	for (int w = 1, p = 1, i; p < n; w <<= 1, m = p)
	{
		for (p = 0, i = n - w + 1; i <= n; ++i) tp[++p] = i;
		for (i = 1; i <= n; ++i) if (sa[i] > w) tp[++p] = sa[i] - w;
		Rsort(), swap(rk, tp), rk[sa[1]] = p = 1;
		for (int i = 2; i <= n; ++i) rk[sa[i]] = cmp(tp, sa[i], sa[i - 1], w) ? p : ++p;
	}
	/*int j, k = 0;
	for (int i = 1; i <= n; height[rk[i++]] = k)
		for (k = k ? k - 1 : k, j = sa[rk[i] - 1]; s[i + k] == s[j + k]; ++k);*/
}
inline bool check(int x)
{
	int p;
	for (int i = 1; i <= m; ++i)
	{
		int t = i; p = k;
		while (p--)
		{
			if (rk[t] <= x) t += m;
			else t += m - 1;
			if (t >= n + i) return true;
		}
	}
	return false;
}
int main()
{
	scanf("%d%d", &n, &k);
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i) s[i + n] = s[i];
	n <<= 1; Suffix();
	n >>= 1;
	int l = 1, r = n << 1, mid;
	m = (n - 1) / k + 1;//最长的长度
	while (l < r)
	{
		mid = (l + r) >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	for (int i = 1; i <= n; ++i)
		if (rk[i] == l)
			for (int j = i; j < i + m; ++j) putchar(s[j]);
	return 0;
}

top

L 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 405
#define p 1000000007
#define ll long long
int n,m,c,fac[maxn],inv[maxn],Pow[maxn*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()
{
	read(n),read(m),read(c);
	fac[0]=inv[0]=1;
	for(int i=1;i<=400;++i) fac[i]=1ll*fac[i-1]*i%p;
	inv[400]=qpow(fac[400],p-2);
	for(int i=399;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
	ll ans=0,tp;
	for(int k=0;k<=c;++k)
	{
		Pow[0]=1;
		for(int i=1;i<=n*m;++i) Pow[i]=1ll*Pow[i-1]*(c-k+1)%p;
		for(int i=0;i<=n;++i)
			for(int j=0;j<=m;++j)
			{
				tp=1ll*C(n,i)*C(m,j)%p*C(c,k)%p*Pow[(n-i)*(m-j)]%p;
				if((i+j+k)&1) ans-=tp;
				else ans+=tp;
			}
	}
	ans=(ans%p+p)%p;
	printf("%lld\n",ans);
	return 0;
}

top

M code

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 100005
int n;
long long ans,a[maxn];
vector<int> ve,tp;
template<typename T>
T gcd(T a,T b)
{
	if(!b) return a;
	return gcd(b,a%b);
}
int main()
{
	read(n);
	for(int i=1;i<=n;++i) read(a[i]),ans=max(ans,a[i]);
	ve.push_back(1);
	for(int i=2;i<=n;++i)
	{
		tp.clear();tp.push_back(1);
		for(unsigned j=0;j<ve.size();++j)
		{
			#define tmp ve[j]
			a[tmp]=gcd(a[tmp],a[i]);
			ans=max(ans,(i-tmp+1)*a[tmp]);
			if(!j||a[tmp]!=a[ve[j-1]]) tp.push_back(tmp);
		}
		ve=tp;
		if(a[ve.back()]!=a[i]) ve.push_back(i);
	}
	printf("%lld\n",ans);
	return 0;
}

top

posted @ 2020-02-15 10:14  123789456ye  阅读(224)  评论(0编辑  收藏  举报