ZROI week2
$$ZROI week2$$
除草机
首先考虑最少的拐点肯定是那种螺旋形状的,然后手玩几个数据发现和列数(行数)有关,且每增加1就是上一个状态加2,直接\(O(1)\)公式即可
吐槽:为啥\(n,m\)不给成\(10^{18}\)次方??
收集隔膜
一眼就能看出双向搜索,首先打了个暴力企图对拍,先交了上去,\(WA?\),发现和本地输出不一样,搞这个搞了半个小时还是没搞出为什么,然后我用其他的\(IDE\)测发现还是这个毛病,我的双向搜索就没敢交,也不知道改了哪里一个暴力就交过了。
最终得了60分。
- 巧妙的思路:由于贡献是一定的,所以考虑预处理出贡献,一遍\(dfs\)即可。
- 正解的思路:双向搜索,二分查找统计贡献。
翻转序列
想了一会儿想了个线段树的办法,然后疯狂写,一个半小时过去,死了
考虑一个对称中心\(T\),统计出至少多少个字母对称就会产生一个贡献,显然信息量是\(O(N)\)的,这个统计完了之后可以用线段树区间加和区间\(max\)去求解。
然后就死了
事实证明我的方法还是对的
正解就是把线段树统计换成一些奇奇怪怪的,例如前缀和一类的东西。
树
当我写到这个题已经没时间了(10min),想了一会儿想出了正解,对于每条边建立两个点,链内同向,链间反向,在\(LCA\)处统计贡献即可。
懒得写了
还是敲了一手暴力交了上去,本想再拿点分发现没时间了。
正解其实和我思路差不多,考虑把没有贡献的地方缩成一个点,然后快速幂计算即可。
总结与心得
会的总是拿不上分有点难受,希望下次更加努力。
作业
bzoj 4800
题目大意:有\(n\)个物品,\(m\)块钱,给定每个物品的价格,求买物品的方案数
范围:\(n \leq 40,m \leq 10^{18}\)
题解:
如果直接凑是\(2^{40}\)的复杂度,发现贡献是可以合并的,考虑双向搜索,每一半用\(2^{20}\)去搞,最后合并起来即可。
复杂度:\(O(2^{20} + 2^{20})\)
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 1e6 + 10;
ll a[50];
int lim;
int cnt1;
int cnt2;
ll A[MAXN];
ll B[MAXN];
int n;
ll m;
ll ans;
int mid;
void dfs1(int now,ll sum) {
if(now > mid) {
A[++cnt1] = sum;
return;
}
dfs1(now + 1,sum);
if(sum + a[now] <= m) {
dfs1(now + 1,sum + a[now]);
}
}
void dfs2(int now,ll sum) {
if(now > lim) {
B[++cnt2] = sum;
return;
}
dfs2(now + 1,sum);
if(sum + a[now] <= m) {
dfs2(now + 1,sum + a[now]);
}
}
signed main () {
scanf("%d %lld",&n,&m);
for(int i = 1;i <= n; ++i) {
scanf("%lld",&a[++lim]);
if(a[lim] > m) --lim;
}
mid = lim >> 1;
dfs1(1,0);
dfs2(mid + 1,0);
sort(A + 1,A + cnt1 + 1);
sort(B + 1,B + cnt2 + 1);
for(int i = 1,j = cnt2;i <= cnt1; ++i) {
while(A[i] + B[j] > m and j) --j;
if(j == 0) break;
ans += j;
}
cout<<ans<<endl;
return 0;
}
bzoj 1202
第一眼看到觉得是一个差分约束,第二眼觉得是个并查集。。。
并查集:考虑维护一个到根的路径权值,合并时判断即可。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int read () {
int q=0,f=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;ch=getchar();
}
while(isdigit(ch)){
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
int f[MAXN];
int a[MAXN];
int find(int x) {
if(x == f[x]) {
a[x] = 0;
return x;
}
int res = find(f[x]);
a[x] = a[x] + a[f[x]];
return f[x] = res;
}
int n,m;
int tag;
int main () {
// freopen("1.in","r",stdin);
// freopen("ans.out","w",stdout);
int T = read();
while(T--) {
tag = 0;
n = read(),m = read();
for(int i = 1;i <= n + 1; ++i) {
f[i] = i;
}
memset(a,0,sizeof a);
while(m--) {
int s = read(),t = read(),val = read();
int l = find(s);
int r = find(t + 1);
if(l != r) {
f[l] = r;
a[l] = a[t + 1] - a[s] - val;
}
else if(a[t + 1] - a[s] != val) tag = 1;
}
cout<<(tag == 0 ? "true" : "false")<<endl;
}
return 0;
}
差分约束:按照输入的方法建一张图,跑可行的\(spfa\)即可。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int read () {
int q=0,f=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;ch=getchar();
}
while(isdigit(ch)){
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
int n,m;
struct edge {
int to;
int nxt;
int w;
}e[MAXN << 1];
int cnt;
int vis[MAXN << 1];
int inq[MAXN << 1];
int dis[MAXN << 1];
int head[MAXN << 1];
void add(int u,int v,int w) {
e[++cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
e[cnt].w = w;
}
int spfa(int now) {
vis[now] = 1;
inq[now] = 1;
for(int i = head[now];i;i=e[i].nxt) {
int y = e[i].to;
if(dis[y] > dis[now] + e[i].w) {
dis[y] = dis[now] + e[i].w;
if(inq[y] or spfa(y) == 0) return 0;
}
}
inq[now] = 0;
return 1;
}
int tag;
int T;
int main () {
//freopen("1.in","r",stdin);
//freopen("ans.out","w",stdout);
T = read();
while(T--) {
n = read(),m = read();
cnt = 0;
memset(inq,0,sizeof inq);
memset(vis,0,sizeof vis);
memset(head,0,sizeof head);
memset(dis,0x3f,sizeof dis);
for(int i = 1;i <= m; ++i) {
int x = read(),y = read(),z = read();
add(x ,y - 1,z);
add(y - 1, x , z);
}
tag = 0;
for(int i = 0;i <= n; ++i) {
if(!vis[i]) {
dis[i] = 0;
cout<<spfa(i)<<endl;
if(spfa(i) == 0) {
puts("false");
tag = 1;
break;
}
}
}
if(!tag) puts("true");
}
return 0;
}
bzoj 2679
吐槽:\(map\)定义的\(vis\)数组难道不能标记?
本意就是相当于将一些数划分成两个相等的集合,这里集合相等表示集合的数之和相等,数可以不划分完。
直接处理是\(3^n\)的,为什么?
对于每个数有三种情况:选到左边,选到右边,不选。
直接暴力的话就是\(3^{20}\),显然是不行的。
考虑折半搜索,先处理一半的数据,再在另一半中找和,判断状态是否相同加和即可。
注意不要算0.
upd : 注意判重
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1 << 22;
int n;
int a[41];
int vis[MAXN];
int ans;
vector<int>v[MAXN];
map<int,int> mp;
map <int ,int > jud;
int cnt;
#define mid n / 2
void dfs1(int now,int sum,int sta) {
if(now > mid) {
if(!mp.count(sum)) {
mp[sum] = ++cnt;
}
v[mp[sum]].push_back(sta);
return;
}
dfs1(now + 1,sum + a[now],sta | (1 << (now - 1)));
dfs1(now + 1,sum - a[now],sta | (1 << (now - 1)));
dfs1(now + 1,sum,sta);
}
void dfs2(int now,int sum,int sta) {
if(now > n) {
if(!mp.count(sum)) {
return;
}
int res = mp[sum];
if(jud[res] == 0) {
sort(v[res].begin(),v[res].end());
v[res].resize(unique(v[res].begin(),v[res].end()) - v[res].begin());
jud[res] = 1;
}
for(int i = 0;i < v[res].size(); ++i) {
if(!vis[v[res][i] | sta]) {
ans ++;
}
vis[v[res][i] | sta] = 1;
}
return;
}
dfs2(now + 1,sum + a[now],sta | (1 << (now - 1)));
dfs2(now + 1,sum - a[now],sta | (1 << (now - 1)));
dfs2(now + 1,sum,sta);
}
int main () {
cin >> n;
for(int i = 1;i <= n; ++i) {
cin >> a[i];
}
dfs1(1,0,0);
dfs2(mid+1,0,0);
cout<<ans - 1<<endl;
return 0;
}
bzoj 3211
区间修改和查询
树状数组维护即可,对于开根操作暴力即可,数据比较水...
或者写个线段树维护单点开根的\(tag\)。
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define lowbit(x) x & -x
#define int long long
const int MAXN = 3e6 + 10;
int c[MAXN];
int a[MAXN];
int num[MAXN];
int n;
int m;
int read () {
int q=0,f=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;ch=getchar();
}
while(isdigit(ch)) {
q=q*10+ch-'0';ch=getchar();
}
return q*f;
}
void add(int x,int k) {
for(int i = x;i <= n;i += lowbit(i)) {
c[i] += k;
}return;
}
int ck(int x) {
int ans = 0;
for(int i = x;i; i -= lowbit(i)) {
ans += c[i];
}
return ans;
}
int get1(int l,int r) {
return r - l + 1 - (num[r] - num[l - 1]);
}
void change(int l,int r) {
if(ck(r) - ck(l - 1) <= get1(l,r)) return;
for(int i = l;i <= r; ++i) {
if(a[i] > 1) {
int tmp = sqrt(a[i]);
add(i,tmp - a[i]);
a[i] = tmp;
}
}
}
//#include <ctime>
//clock_t st,ed;
signed main () {
////freopen("11.in","r",stdin);
//freopen("ans.out","w",stdout);
//st = clock();
n = read();
for(int i = 1;i <= n; ++i) {
a[i] = read();
if(a[i] == 0) {
num[i] = num[i - 1] + 1;
}
else num[i] = num[i - 1];
add(i,a[i]);
}
m = read();
for(int i = 1;i <= m; ++i) {
int opt = read(),l = read(),r = read();
if(opt == 1){
cout<<ck(r) - ck(l - 1)<<endl;
}
if(opt == 2) {
change(l,r);
}
}
// ed = clock();
// cout<<(ed - st) / 1000<<endl;
return 0;
}
ZROI week2的更多相关文章
- Spark小课堂Week2 Hello Streaming
Spark小课堂Week2 Hello Streaming 我们是怎么进行数据处理的? 批量方式处理 目前最常采用的是批量方式处理,指非工作时间运行,定时或者事件触发.这种方式的好处是逻辑简单,不影响 ...
- 我的java之路week2类的无参、带参方法
2.1语法 public 返回值类型 方法名(){ //方法体 } 2.2方法的调用语法 对象名.方法名 计算平均分和总成绩 public class Score { /** * 创建类 ScoreC ...
- 海量数据挖掘MMDS week2: 局部敏感哈希Locality-Sensitive Hashing, LSH
http://blog.csdn.net/pipisorry/article/details/48858661 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...
- 集大软件工程15级个人作业Week2
集大软件工程15级个人作业Week2 快速通读教材<构建之法>,并参照提问模板,提出5个问题. 在每个问题后面,请说明哪一章节的什么内容引起了你的提问,提供一些上下文 列出一些事例或资料, ...
- [buaa-SE-2017]个人作业-Week2
个人作业-Week2 一.代码复审Checklist 1.概要部分 1.1 代码能符合需求和规格说明么? 本次作业的需求可以分成基本的功能实现和大规模数据下程序的健壮性,以及少量的异常处理能力,也就是 ...
- Internet History, Technology and Security (Week2)
Week2. History: The First Internet - NSFNet coursera address Supercomputers Justify a National Netwo ...
- 陈爽 软件工程导论week2.1
软件工程导论week2.1 第一章概论问题:1.程序=算法+数据结构 软件=程序+软件工程软件工程的目标是创造足够好的软件,可以从用户满意度,可靠性,软件流程的质量,可维护性等方面判断,但是我们没有 ...
- 【DeepLearning学习笔记】Coursera课程《Neural Networks and Deep Learning》——Week2 Neural Networks Basics课堂笔记
Coursera课程<Neural Networks and Deep Learning> deeplearning.ai Week2 Neural Networks Basics 2.1 ...
- 【Python学习笔记】Coursera课程《Using Python to Access Web Data 》 密歇根大学 Charles Severance——Week2 Regular Expressions课堂笔记
Coursera课程<Using Python to Access Web Data > 密歇根大学 Charles Severance Week2 Regular Expressions ...
随机推荐
- 使用SSH 工具 Xshell 6连接CentOS 7.4
在使用Xshell 6连接 服务CentOS 7.4之前,首先你要配置好服务器,如果没有配置好服务器的,请访问: (一)小白教小白配置 服务器 好了,开始正文! 首先准备,SSH 工具 Xshell ...
- Python操作 Memcache
Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据 库驱动网站的速 ...
- vs 2019 create new project 创建新项目
下面的place solution and project in the same directory 不需要勾选
- ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.win.mall.dao.CartMapper.test’. It’s likely that neither a Result Type nor a Result Map was specified.
ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.win.m ...
- dex2jar反编译大文件内存溢出的问题
@echo off REM better invocation scripts for windows from lanchon, release in public domain. thanks! ...
- Python Django 编写一个简易的后台管理工具3-运行项目
编写view页面 def hello(request): return render(request,'hello.html') 编写html页面 <!DOCTYPE html> < ...
- RSTP生成树
一.实验目的 二.实验拓扑图 三.实验编址 四.实验步骤 1.基本步骤 配置PC机IP 配置完成,开启所有设备,测试主机之间连通性 2.配置RSTP基本功能 在四台交换机上修改生成树模式:配置完成后, ...
- QTP使用dictionary 对象
1. 创建即使用Dictionary对象 ' 创建Dictionary对象Set Dic = CreateObject("Scripting.Dictionary")' 添加Dic ...
- C++中的函数重载分析(二)
1,重载与指针: 1,下面的函数指针将保存哪个函数的地址? int func(int x) { return x; } int func(int a, int b) { return a + b; } ...
- Liunx平台安装MySQL操作步骤
使用yum安装MySQL 第一步 第二步 第三步 数据库安装成功 修改数据库密码,并且删除匿名用户.禁止root远程登录.删除test数据库.刷新权限. 使用命令进入后,找到自己的临时密码,并且修改 ...