A. Anu Has a Function
容易发现
B. Aerodynamic
将图形
但这样做不够好,观察样例可以看出,这个图形必须是中心对称的。那么就有结论:
C. Water Balance
一道和 【NOI2016】国王饮水记 很相似的题,看到题我就往斜率上想的。。
求字典序最小就是套路的依次确定,也就是固定了一段区间的左端点去找右端点,使这段的平均值最小。设序列的前缀和为
对于这个式子,可以将
#include <cstdio>
typedef long long ll;
const int MAXN=1100000;
int a[MAXN]; ll s[MAXN];
int q[MAXN];
int main()
{
// freopen("C.in", "r", stdin);
// freopen("C.out", "w", stdout);
int n, k=0;
scanf("%d", &n);
for (int i=1; i<=n; i++) scanf("%d", &a[i]);
q[++k]=0;
for (int i=1; i<=n; i++)
{
s[i]=s[i-1]+a[i];
while (k>=2&&(s[i]-s[q[k]])*(q[k]-q[k-1])<=(s[q[k]]-s[q[k-1]])*(i-q[k])) k--;
q[++k]=i;
}
for (int i=1, j=1; i<=n; i=q[j]+1)
{
while (j<k&&(s[q[j+1]]-s[i-1])*(q[j]-i+1)<=(s[q[j]]-s[i-1])*(q[j+1]-i+1)) j++;
double t=1.0*(s[q[j]]-s[i-1])/(q[j]-i+1);
for (int p=i; p<=q[j]; p++) printf("%.10lf\n", t);
}
return 0;
}
D. Around the World
好题。和线性代数有一点相关。
考虑把
对于一个连通分量,只经过它的非平凡环的异或值的取值实际上就是这个分量里所有简单环的异或值。考虑它的任意一棵 DFS 树,对于它的每条非树边,求出这条边与树边构成的简单环的异或值,把它看成一个向量插入线性基中。那么这个线性基就是这些向量的扩张的最小生成集(感性理解)。如果有一组向量线性相关(即一个向量无法被插入线性基),那么显然这个分量里有异或为
接下来考虑 DP。对于每个连通分量有
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
const int MAXN=110000;
const int MAXC=400;
const int P=1E9+7;
struct Edge
{
int to, val;
Edge(int v, int w): to(v), val(w) {}
};
struct XorBasis
{
int d[5];
void clear()
{
d[0]=d[1]=d[2]=d[3]=d[4]=0;
}
bool insert(int x)
{
for (int i=4; i>=0; i--)
if (x&1<<i)
if (d[i]) x^=d[i];
else
{
d[i]=x;
for (int j=0; j<i; j++)
if (d[j]&&d[i]&1<<j) d[i]^=d[j];
for (int j=i+1; j<5; j++)
if (d[j]&1<<i) d[j]^=d[i];
return 1;
}
return 0;
}
int space()
{
return d[0]|d[1]<<1|d[2]<<3|d[3]<<6|d[4]<<10;
}
};
vector<Edge> g[MAXN];
int dfc, dfn[MAXN], val[MAXN];
int cnt, id[MAXN]; XorBasis bas[MAXC];
int trans[MAXC][MAXC];
int blk, p1[MAXN], p2[MAXN];
int f[MAXN][MAXC];
inline int add(int& x, int y)
{
x+=y;
if (x>=P) x-=P;
}
void dfs(int u, int f)
{
static XorBasis xb;
static int cir;
dfn[u]=++dfc;
for (int i=0; i<g[u].size(); i++)
{
int v=g[u][i].to, w=g[u][i].val;
if (!dfn[v])
{
if (u==1) xb.clear(), cir=-1, blk++;
val[v]=val[u]^w; dfs(v, u);
}
else if (dfn[v]<dfn[u]&&v!=f)
if (v==1) cir=val[u]^val[v]^w;
else if (!xb.insert(val[u]^val[v]^w))
p1[blk]=p2[blk]=-1;
}
if (f==1&&~p1[blk])
{
p1[blk]=xb.space();
if (~cir)
{
p2[blk]=p1[blk];
if (xb.insert(cir)) p1[blk]=xb.space();
else p1[blk]=-1;
}
else p2[blk]=-1;
}
}
int main()
{
// freopen("D.in", "r", stdin);
// freopen("D.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for (int i=1; i<=m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(Edge(v, w));
g[v].push_back(Edge(u, w));
}
for (int t[5]={0}; t[0]<32; t[0]++)
for (t[1]=t[0]; t[1]<32; t[1]++)
for (t[2]=t[1]; t[2]<32; t[2]++)
for (t[3]=t[2]; t[3]<32; t[3]++)
for (t[4]=t[3]; t[4]<32; t[4]++)
{
XorBasis tmp; tmp.clear();
for (int i=0; i<5; i++) tmp.insert(t[i]);
int p=tmp.space();
if (!id[p]) id[p]=++cnt, bas[cnt]=tmp;
}
for (int i=1; i<=cnt; i++)
for (int j=1; j<=cnt; j++)
{
XorBasis tmp=bas[i];
for (int k=0; k<5; k++)
if (bas[j].d[k]&&!tmp.insert(bas[j].d[k]))
{ trans[i][j]=-1; break; }
if (~trans[i][j]) trans[i][j]=tmp.space();
}
dfs(1, 0);
f[0][1]=1;
for (int i=1; i<=blk; i++)
for (int j=1; j<=cnt; j++)
{
add(f[i][j], f[i-1][j]);
if (~p1[i]&&~trans[j][id[p1[i]]])
add(f[i][id[trans[j][id[p1[i]]]]], f[i-1][j]);
if (~p2[i]&&~trans[j][id[p2[i]]])
add(f[i][id[trans[j][id[p2[i]]]]], 2*f[i-1][j]%P);
}
int ans=0;
for (int i=1; i<=cnt; i++)
ans=(ans+f[blk][i])%P;
printf("%d\n", ans);
return 0;
}