..拿金了 没给学校丢脸

A

....SB题啊 比赛的时候都没看 裸的一个bitset前缀和

先开一个1e4*1e4的二维bitset数组 初始第i个数组的值为1 << i (即B[i]=1 B[i]<<=i)

很容易我们可以知道要单独翻转某一位而不去影响其他位的话 方法是唯一的

然后我们从可以后往前DP 就可以知道要单独翻转某一位的话需要翻转那些位

最后的每次翻转过后的答案就是   上一个答案^PreL-1 ^PreR

注意用cout的话容易System Error......(再喷一次OJ

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[][] = {{, }, {, }, {, -}, { -, }, {, }, {, -}, { -, -}, { -, }};
const int mod = 1e9 + , gakki = + + + + 1e9;
const int MAXN = 1e5 + , MAXM = 1e5 + , N = 1e4 + ;
const int MAXQ = ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], tot = ;
inline void addedge(int u, int v)
{
to[++tot] = v;
nxt[tot] = Head[u];
Head[u] = tot;
}
inline void read(int &v)
{
v = ;
char c = ;
int p = ;
while (c < '' || c > '')
{
if (c == '-')
{
p = -;
}
c = getchar();
}
while (c >= '' && c <= '')
{
v = (v << ) + (v << ) + c - '';
c = getchar();
}
v *= p;
}
int n, m, l, r;
bitset<N> B[], pre[], ans;
int main()
{
ios_base::sync_with_stdio();
cin.tie();
int T;
read(T);
while (T--)
{
ans.reset();
read(n), read(m);
for (int i = ; i <= n; i++)
{
B[i].reset();
}
B[] = ;
for (int i = n; i >= ; i--)
{
B[i] = ;
B[i] <<= i;
for (int j = * i; j <= n; j += i)
{
B[i] = B[i] ^ B[j];
}
}
pre[] = ;
for (int i = ; i <= n; i++)
{
pre[i] = pre[i - ] ^ B[i];
}
for (int i = ; i <= m; i++)
{
read(l), read(r);
ans = ans ^ pre[l - ] ^ pre[r];
printf("%d\n", ans.count());
}
}
return ;
}

B(比赛通过)

水题

C(比赛通过)

把不同的字符串看作是点

用AC自动机建边 跑一遍即可

D

最后没有时间了 没做出来 其实蛮简单的

在没有确定根之前 满足一对pilot要求的点是这两个点的子树

在确定了一个节点为根之后 就可以分为两种情况

1.两个pilot不是一条链上的 则两个点的子树+1

2.两个pilot是一条链上的 则先全部节点+1 再把父亲到这个儿子的子树(不包括父亲节点)-1 再把儿子的子树+1

最后看值为m的点有多少个 即为答案+1 -1的这些操作用一个数组维护 dfs从父亲到儿子作前缀和即可

可以倍增(NlogN)做 也可以tarjan+dfs序(N)

倍增:

加读入挂的话 可以减到5500ms

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[][] = {{, }, {, }, {, -}, { -, }, {, }, {, -}, { -, -}, { -, }};
const int mod = 1e9 + , gakki = + + + + 1e9;
const int MAXN = 1e5 + , MAXM = 1e5 + ;
const int maxl = ;
const int MAXQ = ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], tot = ;
inline void addedge(int u, int v)
{
to[++tot] = v;
nxt[tot] = Head[u];
Head[u] = tot;
}
int flag = ;
int n, m, anser = ;
int presum[MAXN];
int grand[MAXN][maxl]; //x向上跳2^i次方的节点,x到他上面祖先2^i次方的距离
int gw[MAXN][maxl]; //维护距离的数组
int depth[MAXN];//深度
int root;
int N; //N的意思是最多能跳几层
void dfs(int x)//dfs建图
{
for (int i = ; i <= N; i++) //第一个几点就全部都是0,第二个节点就有变化了,不理解的话建议复制代码输出下这些数组
{
grand[x][i] = grand[grand[x][i - ]][i - ]; //倍增 2^i=2^(i-1)+2^(i-1)
}
for (int i = Head[x]; i; i = nxt[i])
{
int v = to[i];
if (v != grand[x][])
{
depth[v] = depth[x] + ;
grand[v][] = x;
dfs(v);
}
}
}
void Init()
{
tot = ;
anser = ;
for (int i = ; i <= n; i++)
{
presum[i] = Head[i] = ;
}
N = floor(log(n + 0.0) / log(2.0));//最多能跳的2^i祖先
depth[root] = ; //根结点的祖先不存在,用-1表示
depth[] = -;
memset(grand, , sizeof(grand));
}
int lca(int a, int b)
{
if (depth[a] > depth[b])
{
swap(a, b); //保证a在b上面,便于计算
}
int ans = ;
for (int i = N; i >= ; i--) //类似于二进制拆分,从大到小尝试
{
if (depth[a] < depth[b] && depth[grand[b][i]] >= depth[a]) //a在b下面且b向上跳后不会到a上面
{
b = grand[b][i]; //先把深度较大的b往上跳
}
}
if (a == b)
{
return a;
}
for (int j = N; j >= ; j--) //在同一高度了,他们一起向上跳,跳他们不相同节点,当全都跳完之后grand【a】【0】就是lca,上面有解释哈。
{
if (grand[a][j] != grand[b][j])
{
a = grand[a][j];
b = grand[b][j];
}
}
return grand[a][];
}
int lca2(int a, int b)
{
if (depth[a] > depth[b])
{
swap(a, b); //保证a在b上面,便于计算
}
int ans = ;
for (int i = N; i >= ; i--) //类似于二进制拆分,从大到小尝试
{
if (depth[a] + < depth[b] && depth[grand[b][i]] >= depth[a] + ) //a在b下面且b向上跳后不会到a上面
{
b = grand[b][i]; //先把深度较大的b往上跳
}
}
return b;
}
void getadd(int x, int fa)
{
presum[x] += presum[fa];
for (int i = Head[x]; i; i = nxt[i])
{
int v = to[i];
if (v != fa)
{
getadd(v, x);
}
}
}
int main()
{
ios_base::sync_with_stdio();
cin.tie();
root = ;
int T;
scanf("%d",&T);
while (T--)
{
int u, v;
scanf("%d %d", &n, &m);
Init();
for (int i = ; i <= n - ; i++)
{
scanf("%d %d", &u, &v);
addedge(u, v), addedge(v, u);
}
dfs(root);
for (int i = ; i <= m; i++)
{
scanf("%d %d", &u, &v);
int now = lca(u, v);
//cout << "lca" << now << endl;
if (now == u || now == v)
{
int cnt = lca2(u, v);
//cout << "lca2 " << cnt << endl;
if (now == u)
{
presum[]++;
presum[cnt]--;
presum[v]++;
}
else
{
presum[]++;
presum[cnt]--;
presum[u]++;
}
}
else
{
presum[u]++, presum[v]++;
}
}
getadd(, );
// for (int i = 1; i <= n; i++)
// {
// cout << "presum" << i << " " << presum[i] << endl;
// }
for (int i = ; i <= n; i++)
{
if (presum[i] == m)
{
//cout << i << endl;
anser++;
}
}
cout<<anser<<endl;
}
return ;
}

tarjan做法:

没有用到dfs序 只是dfs的时候记录了一下当前节点的儿子节点QQQnxt[u]=v

极限可以做到2500ms

更新:莫名其妙他们的OJ变快(正常)了 跑了340ms 上面的倍增则跑了1000ms

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[][] = {{, }, {, }, {, -}, { -, }, {, }, {, -}, { -, -}, { -, }};
const int mod = 1e9 + , gakki = + + + + 1e9;
const int MAXN = 1e5 + , MAXM = 1e5 + , N = 1e5 + ;
const int MAXQ = ;
int to[MAXM << ], nxt[MAXM << ], Head[MAXN], tot = ;
inline void addedge(int u, int v)
{
to[++tot] = v;
nxt[tot] = Head[u];
Head[u] = tot;
}
inline void read(int &v)
{
v = ;
char c = ;
int p = ;
while (c < '' || c > '')
{
if (c == '-')
{
p = -;
}
c = getchar();
}
while (c >= '' && c <= '')
{
v = (v << ) + (v << ) + c - '';
c = getchar();
}
v *= p;
}
int QQQnxt[MAXN];
int QQQanser[MAXN];
pair<int, int> QQQ[MAXM];
int n, m, anser = ;
int presum[MAXN], ans[MAXN];
bool vis[MAXN];//访问标记
int ancestor[MAXN];//祖先
struct Query
{
int q, next;
int index;//查询编号
} query[MAXQ * ];
int tt, Q, h[MAXQ], answer[MAXQ];
int F[MAXN];//需要初始化为-1
int find(int x)
{
if (F[x] == -)
{
return x;
}
return F[x] = find(F[x]);
}
void bing(int u, int v)
{
int t1 = find(u);
int t2 = find(v);
if (t1 != t2)
{
F[t1] = t2;
}
}
inline void add_query(int u, int v, int index)
{
query[tt].q = v;
query[tt].next = h[u];
query[tt].index = index;
h[u] = tt++;
query[tt].q = u;
query[tt].next = h[v];
query[tt].index = index;
h[v] = tt++;
}
void LCA(int u)
{
ancestor[u] = u;
vis[u] = true;
for (int i = Head[u]; i; i = nxt[i])
{
int v = to[i];
QQQnxt[u] = v;
if (vis[v])
{
continue;
}
LCA(v);
bing(u, v);
ancestor[find(u)] = u;
}
for (int i = h[u]; i != -; i = query[i].next)
{
int v = query[i].q;
if (vis[v])
{
answer[query[i].index] = ancestor[find(v)];
if (answer[query[i].index] == v)
{
QQQanser[query[i].index] = QQQnxt[v];
}
}
}
}
void init()
{
tt = tot = ;
anser = ;
for (int i = ; i <= n; i++)
{
ancestor[i] = presum[i] = Head[i] = ;
vis[i] = F[i] = h[i] = -;
}
}
void getadd(int x, int fa)
{
presum[x] += presum[fa];
for (int i = Head[x]; i; i = nxt[i])
{
int v = to[i];
if (v != fa)
{
getadd(v, x);
}
}
}
int main()
{
ios_base::sync_with_stdio();
cin.tie();
int T;
read(T);
while (T--)
{
int u, v;
read(n), read(m);
init();
for (int i = ; i <= n - ; i++)
{
read(u), read(v);
addedge(u, v), addedge(v, u);
}
for (int i = ; i < m; i++)
{
read(u), read(v);
add_query(u, v, i);
QQQ[i] = make_pair(u, v);
}
LCA();
for (int i = ; i < m; i++)
{
//cout << answer[i] << endl;
if (answer[i] == QQQ[i].first)
{
//cout<<QQQanser[i]<<endl;
presum[]++;
presum[QQQanser[i]]--;
presum[QQQ[i].second]++;
}
else if (answer[i] == QQQ[i].second)
{
//cout<<QQQanser[i]<<endl;
presum[]++;
presum[QQQanser[i]]--;
presum[QQQ[i].first]++;
}
else
{
presum[QQQ[i].first]++;
presum[QQQ[i].second]++;
}
}
getadd(, );
// for (int i = 1; i <= n; i++)
// {
// cout << "presum" << i << " " << presum[i] << endl;
// cout << "ans" << i << " " << ans[i] << endl;
// }
for (int i = ; i <= n; i++)
{
if (presum[i] == m)
{
//cout << i << endl;
anser++;
}
}
printf("%d\n", anser);
}
return ;
}

E(比赛通过)

注意年=月=日的特殊合法情况即可

F(比赛通过)

如果知道中位数的话 我们就可以n2logn暴力地知道答案 剩下就是怎么找中位数的问题

找中位数可以用权值线段树来做 注意单个点权值占一半以上的情况

总复杂度3*T*n2logn/2

G

无视

H(比赛通过)

水题

I(比赛通过)

树分治中点分治的一个小部分 变成带权的了 直接dfs一次即可

J(比赛通过)

结论题

很容易可以知道前三个我们肯定是可以确认是原数列的前三个

因为A0=0   A0+A1   A0+A2这三个肯定是最小的

比如样例0 1 2 2 我们可以先确认前三个0 1 2

则这三个产生的数列是1 2 3 接下来我们看与目标数列1 2 2 3 3 4对比最小的缺什么

很容易发现缺了个2 所以我们必须补个2

因为数列是非递减的Ai与之前数相加产生的数不大于Ai+1与之前数相加所产生的数

这样继续check直到数列被填满

写的话就是直接暴力找 看起来复杂度会爆炸 但其实中间很多就直接break相当于剪枝了 能过

K

题意:

你要玩一个猜数游戏 答案为X 你最多只能问N次 问的时间最多不能超过V

第i次询问你可以选一个数Y猜 如果Y大于X的话 会花费Ai的时间 不然的话会花费Ai+Bi的时间

你只有每次猜完后才可以猜下一次 问你最后可以从1开始猜到的最大区间长度为多少

解:

dp dp[i][j]表示只使用询问 i到n 而且时间不超过j所能知道的答案

dp[i][j] = dp[i+1][j-Ai] + dp[i+1][j-Ai-Bi]  但是边界的时候需要考虑一些细节... 

2018年第十届ACMICPC四川省大学程序设计竞赛的更多相关文章

  1. 第十四届浙江财经大学程序设计竞赛重现赛--A-A Sad Story

    链接:https://www.nowcoder.com/acm/contest/89/A 来源:牛客网 1.题目描述 The Great Wall story of Meng Jiangnv’s Bi ...

  2. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  3. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  4. A. Srdce and Triangle--“今日头条杯”首届湖北省大学程序设计竞赛(网络同步赛)

    如下图这是“今日头条杯”首届湖北省大学程序设计竞赛的第一题,作为赛后补题 题目描述:链接点此 这套题的github地址(里面包含了数据,题解,现场排名):点此 Let  be a regualr tr ...

  5. 2018年 第43届ACM-ICPC亚洲区域赛(青岛)现场赛 赛后总结

    下了动车后,又颠颠簸簸的在公交车上过了接近一个小时,本来就晕车,于是,到的时候脑子晕死了,而且想吐.可能是没吃早饭的缘故,午饭好好次QWQ. 开幕式 还是第一次在这种环境下参赛,记得以前是看老师发的学 ...

  6. 2018 ACM-ICPC 中国大学生程序设计竞赛暨丝绸之路程序设计竞赛

    三道大水题,其它题都不会做,真是尴尬和无奈啊…… 有想法,但是解决不了,感觉个人不会一些基本解法,终究还是个人学习的内容太少了 B. Goldbach /* 数值较小,<2^63,分解的两个素数 ...

  7. 计蒜客 25985.Goldbach-米勒拉宾素数判定(大素数) (2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B)

    若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题.一直忘记写博客,备忘一下. 米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~ B. Goldbach 题目 ...

  8. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 I. Reversion Count (java大数)

    Description: There is a positive integer X, X's reversion count is Y. For example, X=123, Y=321; X=1 ...

  9. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 D Merchandise (斜率优化)

    Description: The elderly aunts always like to look for bargains and preferential merchandise. Now th ...

随机推荐

  1. Windows删除文件夹下的指定格式文件(递归删除)

    问题描述: 今天遇到一个需求,需要对文件夹进行文件筛选.目录结构较为复杂(目录较多,层次较深),数据量较大(总共60GB左右). 鉴于上述情况,直接排除了人工处理方式(否则小伙伴们会打死我的). 解决 ...

  2. javascript中var、let、const的区别

    这几天修改别人的js,发现声明变量有的用var,有的用let,那它们有什么区别呢? javascript中声明变量的方式有:var.let.const 1.var (1)作用域: 整个函数范围内,或者 ...

  3. 记事本 该文件含有unicode格式的字符 点确定就变乱码了,notePad++,UltraEditor等编辑器打开也变乱码?

    --问题 之前一直都是好的 今天电脑打开,发现电脑所有的TXT记事本,点开来全是乱码,甚至下过来的TXT,或者自己新建的TXT,打上中文字,点保存会弹出 该文件含有unicode格式的字符什么什么的, ...

  4. Delphi Mercadopago支付【支持支持获取账户信息和余额、创建商店,商店查询、创建二维码、二维码查询、创建订单、订单查询、订单退款等功能】

    作者QQ:(648437169) 点击下载➨Delphi Mercadopago支付 [Delphi Mercadopago支付]支持 支持支持获取账户信息和余额.创建商店,商店查询.创建二维码.二维 ...

  5. 【LEETCODE】66、字符串分类,hard级别,题目:32,72,76

    package y2019.Algorithm.str.hard; import java.util.Stack; /** * @ProjectName: cutter-point * @Packag ...

  6. 三伏天里小试牛刀andriod 开发 #华为云·寻找黑马程序员#【华为云技术分享】

    2019年07月,北京,三伏天,好热啊.越热自己还越懒得动换(肉身给的信号),但是做为产品经理/交互设计师的,总想着思考些什么(灵魂上给的信号),或者是学习些什么,更有利于将来的职业发展吧,哈哈哈.工 ...

  7. python3的pip3安装

    ---恢复内容开始--- pip3的安装需要对应一整套python的编译工具库,所以安装好的pip3是这个样子: inear@Ai:~$ pip3 -V pip 18.1 from /usr/lib/ ...

  8. SpringBoot整合freemarker 引用基础

    原 ElasticSearch学习笔记Ⅲ - SpringBoot整合ES 新建一个SpringBoot项目.添加es的maven坐标如下: <dependency> <groupI ...

  9. .NET 的程序集加载上下文

    原文:.NET 的程序集加载上下文 我们编写的 .NET 应用程序会使用到各种各样的依赖库.我们都知道 CLR 会在一些路径下帮助我们程序找到依赖,但如果我们需要手动控制程序集加载路径的话,需要了解程 ...

  10. Windows 2003 服务器 关闭IIS中FTP匿名访问

    控制面板 –> 管理工具 –> Internet信息服务管理器打开后左侧选择相应的FTP站点右击 –> 属性 –> 安全帐户允许匿名连接 前面的√取消掉,点击确定完成