JSOI2015
JSOI2015
A salsman
题面:Luogu
题解:树形dp
考虑设\(dp[u]\)表示经过\(u\)及其子树的最大收益
停留次数就把子树的收益算一下排个序取前多少个就好了
第二问的话不是独自的有几种情况
- 这颗子树的选了的和没选的有收益相同的
- 有选了收益0的(也就是可选可不选)
- 子树里有不是独自的
分类讨论一下即可
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\)种颜色不用,随意涂
则此时答案为
其中\(c-k+1\)是因为还可以不涂
于是容斥一下
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
There is a negligible beginning in all great action and thought.