难度:☆☆☆☆☆☆☆

/*
可以先考虑一维,可知 模k意义下相同的前缀和任意两个相减都是k的倍数
问题等价于统计前缀何种模k相同的数的对数。
多维的时候二维前缀和,压行或者压列,n^3可以解决。
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> #define K 1000007
#define N 400 using namespace std;
typedef long long LL;
int f[K],s[N][N]; int main()
{
freopen("rally.in", "r", stdin);
freopen("rally.out", "w", stdout);
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
scanf("%d",s[i]+j);
s[i][j]+=s[i-][j]+s[i][j-]-s[i-][j-];
if (s[i][j]<) s[i][j]+=k;
if (s[i][j]>) s[i][j]%=k;
}
LL ans=;
f[]=;
for (int l=;l<=m;l++)
for (int r=l;r<=m;r++)
{
for (int i=;i<= n;i++)
{
int sum=s[i][r]-s[i][l-];
if (sum<) sum+=k;
ans+=f[sum];f[sum]++;
}
for (int i=;i<=n;i++)
{
int sum=s[i][r]-s[i][l-];
if (sum<) sum+=k;f[sum]--;
}
}
printf("%lld\n",ans);
return ;
}

/*
树形dp可做,好难好难的样子
考虑贪心 暗点的深度排序,每次拿出未被更新的最深的点把他的k级父亲标记
然后用这个点向外扩展更新每个点距离标记点的距离
正确性显然
*/
#include<iostream>
#include<cstdio>
#include<cstring> #define N 100007 using namespace std;
int head[N],q[N],f[N],fa[N];
int n,m,ans,cnt,K,t;
struct edge{
int u,v,net;
}e[N<<]; inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline void add(int u,int v)
{
e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt;
} void bfs()
{
int he=,ta=;
q[ta++]=;fa[]=;
while(he<=ta)
{
int u=q[he++];;
for(int i=head[u];i;i=e[i].net)
{
int v=e[i].v;
if(!fa[v])
{
fa[v]=u;q[ta++]=v;
}
}
}
} void update(int u)
{
if(!f[u]) return;
for(int i=head[u];i;i=e[i].net)
{
int v=e[i].v;
if(f[v]<f[u]-)
f[v]=f[u]-,update(v);
}
} int main()
{
freopen("general.in", "r", stdin);
freopen("general.out", "w", stdout);
int x,y;
n=read();K=read();t=read();
for(int i=;i<n;i++)
{
x=read();y=read();
add(x,y);add(y,x);
}
bfs();
memset(f,-,sizeof f);
for(int i=n;i;i--)
{
if(f[q[i]]==-)
{
int j=q[i];
for(int k=K;k;k--) j=fa[j];
ans++;f[j]=K;
update(j);
}
}
printf("%d\n",ans);
return ;
}

这道题简直了,妙不可言!!!!!!!!!!!!!!

前方高能题解

可是...那个“比较简单的状压dp”怎么写啊......

gg

std

#include <bits/stdc++.h>
using namespace std; typedef pair<int, int> pii;
#define fir first
#define sec second
#define INF 0x3f3f3f3f
#define MAXN 40005
#define TOP 18 int n, K, m, cnt = 0;
bool a[MAXN];
int dis[18][MAXN], b[70];
pii p[18]; queue <int> q; void bfs(pii st)
{
for (int i = 0; i < MAXN; i++) dis[st.fir][i] = INF;
q.push(st.sec);
dis[st.fir][st.sec] = 0;
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i = 1; i <= m; i++)
{
if (x - b[i] >= 0 && dis[st.fir][x - b[i]] > dis[st.fir][x] + 1)
{
dis[st.fir][x - b[i]] = dis[st.fir][x] + 1;
q.push(x - b[i]);
}
if (x + b[i] <= n && dis[st.fir][x + b[i]] > dis[st.fir][x] + 1)
{
dis[st.fir][x + b[i]] = dis[st.fir][x] + 1;
q.push(x + b[i]);
}
}
}
} int dp[1 << 18]; int solve(int mask)
{
if (dp[mask] != -1) return dp[mask];
if (mask == 0) return 0;
int &ret = dp[mask];
ret = INF;
int x = 0;
while (!(mask & (1 << x))) x++;
for (int i = x + 1; i < 2 * K; i++)
if (mask & (1 << i)) ret = min(ret, solve(mask ^ (1 << x) ^ (1 << i)) + dis[x][p[i].sec]);
return ret;
} int main()
{
freopen("starlit.in", "r", stdin);
freopen("starlit.out", "w", stdout);
scanf("%d %d %d", &n, &K, &m);
for (int i = 1, x; i <= K; i++) scanf("%d", &x), a[x] = true;
for (int i = 1; i <= m; i++) scanf("%d", &b[i]);
for (int i = 0; i <= n; i++) if (a[i] != a[i + 1]) p[cnt] = pii(cnt, i), cnt++;
for (int i = 0; i < cnt; i++) bfs(p[i]);
memset(dp, -1, sizeof dp);
int ans = solve((1 << cnt) - 1);
assert(ans != INF);
printf("%d\n", ans);
return 0;
}

  

湖南集训day8的更多相关文章

  1. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  2. P3900 [湖南集训]图样图森破

    P3900 [湖南集训]图样图森破 链接 分析: 感觉像个暴力. 可以枚举回文串的回文中心,即枚举一个串,枚举一个串的位置作为回文中心,然后求出这个串内的回文串的长度. 此时如果回文串两端都没有到这个 ...

  3. [日常训练]常州集训day8

    T1 Description 给定一个长度为$n$的正整数序列$a$.可以将序列分成若干段,定义第$i$段的权值$x_i$为这一段中所有数的最大值,特殊地,$x_0=0$.求$\sum_{i=1}^{ ...

  4. bzoj 3653 [湖南集训]谈笑风生

    题目描述 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  5. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  6. 洛谷P3899 [湖南集训]谈笑风生(线段树合并)

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

  7. P3899 [湖南集训]谈笑风生

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  8. LG3898 [湖南集训]大新闻

    题意 题目描述 **记者弄了个大新闻,这个新闻是一个在 [0,n) 内等概率随机选择的整数,记其为 x.为了尽可能消除这个大新闻对公众造成的不良印象,我们需要在 [0,n)内找到某一个整数 y,使得 ...

  9. 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)

    题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...

随机推荐

  1. 第四章 模块化React和Redux应用

    第四章 模块化React和Redux应用 4.1 模块化应用要点 构建一个应用的基础: 代码文件的组织结构: 确定模块的边界: Store的状态树设计. 4.2 代码文件的组织方式 4.2.1 按角色 ...

  2. CentOS 6磁盘管理

    1.添加4块8G硬盘, 注:要先添加SCSI控制器,再添加SCSI硬盘 2.查看添加的硬盘 3.fdisk分区交互式命令 d delete a partition——————//删除一个分区 n ad ...

  3. idea 背景颜色设置

    1. 设置当前鼠标所在行颜色 2. 设置编辑区颜色

  4. AOP基础

    [Why AOP ?] 1.代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀.每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点. 2.代码分散:以日志需求为例,知识为了 ...

  5. POJ 2065 高斯消元求解问题

    题目大意: f[k] = ∑a[i]*k^i % p 每一个f[k]的值就是字符串上第 k 个元素映射的值,*代表f[k] = 0 , 字母代表f[k] = str[i]-'a'+1 把每一个k^i求 ...

  6. Codeforces Beta Round #91 (Div. 1 Only) E. Lucky Array

    E. Lucky Array Petya loves lucky numbers. Everybody knows that lucky numbers are positive integers w ...

  7. vim下多行注释与解注释

    1.多行注释 (1)按esc进入命令行模式 (2)按下Ctrl+v,进入区块模式,并使用上下键选择需要注释的多行 (3)按下“I”(大写)键,进入插入模式 (4)输入注释符(“//”或“#”等) (5 ...

  8. R - Milking Time DP

    Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that sh ...

  9. P1009 阶乘之和 洛谷

    https://www.luogu.org/problem/show?pid=1009 题目描述 用高精度计算出S=1!+2!+3!+…+n!(n≤50) 其中“!”表示阶乘,例如:5!=54321. ...

  10. codevs——1430 素数判定

    1430 素数判定  时间限制: 1 s  空间限制: 1000 KB  题目等级 : 青铜 Bronze 题解       题目描述 Description 质数又称素数.指在一个大于1的自然数中, ...