Day3上午解题报告
预计分数:100+40+50=190
实际分数:100+40+50=190
T1
https://www.luogu.org/problem/show?pid=T15365
表示从来没做过博弈论的题,
不过在推了40多分钟之后发现有几个结论是肯定对的。。。。
n,m都是奇数,后手胜
否则先手胜
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=1e6;
const int INF=0x7ffff;
inline int read()
{
char c=getchar();int flag=,x=;
while(c<''||c>'') {if(c=='-') flag=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-,c=getchar();return x*flag;
}
int main()
{
// freopen("star.in","r",stdin);
// freopen("star.out","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m))
{
if(n==&&m==) break;
int nowx=n,nowy=;
if(n%==)//A不利
{
printf("Yuri\n");
}
else
{
if(m%==) printf("Yuri\n");
else printf("Chito\n");
}
}
return ;
}
T2
不会做,打40分暴力走人
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<ctime>
using namespace std;
const int MAXN=1e6;
const int INF=0x7ffff;
inline int read()
{
char c=getchar();int flag=,x=;
while(c<''||c>'') {if(c=='-') flag=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-,c=getchar();return x*flag;
}
const int mod=1e9+;
int a[MAXN];
int ans[MAXN];
int anstot=;
int comp(const int &a,const int &b)
{
return a>b;
}
int main()
{
//freopen("war.in","r",stdin);
//freopen("war.out","w",stdout);
int n=read(),k=read();
if(n<=)
{
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(i!=j)
ans[++anstot]=a[i]^a[j];
sort(ans+,ans+anstot+,comp);
int out=;
for(int i=;i<=k;i++)
out=(out+ans[i])%mod;
printf("%d",out);
}
else if(k==)
{
for(int i=;i<=n;i++) a[i]=read();
int t=clock();
sort(a+,a+n+,comp);
int ans=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
ans=max(ans,(a[i]^a[j])%mod)%mod;
if(clock()-t>=)
{
printf("%d",ans);
exit();
}
}
}
printf("%d",ans);
}
else
{
int t=clock();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(i!=j)
{
ans[++anstot]=a[i]^a[j];
if(clock()-t>=)
{
sort(ans+,ans+anstot+,comp);
int out=;
for(int i=;i<=k;i++)
out=(out+ans[i])%mod;
printf("%d",out);
}
}
sort(ans+,ans+anstot+,comp);
int out=;
for(int i=;i<=k;i++)
out=(out+ans[i])%mod;
printf("%d",out);
}
return ;
}
40暴力
正解:
20分k==1
最高位异或==1
假设最大的数只有4位
把所有数遍历一边,看一下第四位是0还是1
考虑分治,对于已经确定的高位,在能选择的区间中观察低一位的能否成为1
最长区间为n
复杂度$O(31*n)$
20分不超过1023
记录0-1023的每个数有多少个
每次暴力枚举
$cnt[a^b]+=cnt[a]*cnt[b]$
正解:
01 trie树
先算第k大是啥,再把比他大的加起来
考虑如何求k->二分
如何求比k大的数:
枚举一个i,那么问题就转化为求有多少个j使得a[i]^a[j]>v(二分的值)
用trie树,从最高位开始枚举
看tire树的右儿子(1)有多少个节点
#define PROC "shana"
#include <cstdio>
#include <cctype>
#include <memory.h>
#include <algorithm>
#include<cctype> using namespace std; typedef long long qw; #define _l (qw)
const int BUF_SIZE = ;
char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + ; #define PTR_NEXT() \
{ \
buf_s ++; \
if (buf_s == buf_t) \
{ \
buf_s = buf; \
buf_t = buf + fread(buf, , BUF_SIZE, stdin); \
} \
} #define readInt(_n_) \
{ \
while (*buf_s != '-' && !isdigit(*buf_s)) \
PTR_NEXT(); \
bool register _nega_ = false; \
if (*buf_s == '-') \
{ \
_nega_ = true; \
PTR_NEXT(); \
} \
int register _x_ = ; \
while (isdigit(*buf_s)) \
{ \
_x_ = _x_ * + *buf_s - ''; \
PTR_NEXT(); \
} \
if (_nega_) \
_x_ = -_x_; \
(_n_) = (_x_); \
} const int maxn = ;
const int maxl = ;
const int maxnd = maxn * maxl;
const int mod = 1e9 + ;
const int inv = ; int v0, n, rt, tn, a[maxn];
int tr[maxnd][], rb[maxnd][maxl], c[maxnd];
qw k; void trieIns(int v) {
int p = rt;
for (int i = maxl - ; i >= ; -- i) {
int v0 = (v >> i) & ;
if (!tr[p][v0])
tr[p][v0] = ++ tn;
p = tr[p][v0];
++ c[p];
for (int j = maxl - ; j >= ; -- j)
if ((v >> j) & )
++ rb[p][j];
}
} int cntUpper(int v, int vu) {
int p = rt, s = ;
for (int i = maxl - ; i >= ; -- i) {
int v0 = (v >> i) & ;
if ((vu >> i) & ) {
p = tr[p][v0 ^ ];
}
else {
s += c[tr[p][v0 ^ ]];
p = tr[p][v0];
}
}
return s;
} qw check(int v) {
qw s = ;
for (int i = ; i < n; ++ i)
s += cntUpper(a[i], v);
return s >> ;
} int sumUpper(int v, int vu) {
int s = , p = rt;
for (int i = maxl - ; i >= ; -- i) {
int v0 = (v >> i) & ;
if ((vu >> i) & )
p = tr[p][v0 ^ ];
else {
for (int j = ; j < maxl; ++ j)
if ((v >> j) & )
s = (_l s + (1LL << j) * (_l c[tr[p][v0 ^ ]] - _l rb[tr[p][v0 ^ ]][j])) % mod;
else
s = (_l s + (1LL << j) * _l rb[tr[p][v0 ^ ]][j]) % mod;
p = tr[p][v0];
}
}
return s;
} int main() {
freopen("war.in", "r", stdin);
freopen("war.out", "w", stdout); readInt(n);
readInt(k);
rt = ;
tn = ;
for (int i = ; i < n; ++ i) {
readInt(a[i]);
trieIns(a[i]);
}
{
int l = , r = ;
while (l < r) {
int mid = (_l l + r + ) >> ;
if (check(mid - ) < k)
r = mid - ;
else
l = mid;
}
v0 = l;
}
if (v0) {
//printf("%d %lld\n", v0, check(v0));
int ans = ;
for (int i = ; i < n; ++ i)
ans = (_l ans + sumUpper(a[i], v0 - )) % mod;
ans = (_l ans * inv % mod + ((k - check(v0 - )) % mod + mod) * _l v0) % mod;
printf("%d\n", ans);
}
else {
int ans = ;
for (int i = ; i < n; ++ i)
ans = (_l ans + sumUpper(a[i], )) % mod;
ans = _l ans * inv % mod;
printf("%d\n", ans);
}
}
T3
https://www.luogu.org/record/lists?uid=36984&pid=T15368
给了40分的暴力分,另外20分是线段树
但是线段树莫名其妙T掉一个点。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int MAXN=4e6;
const int INF=0x7ffff;
inline int read()
{
char c=getchar();int flag=,x=;
while(c<''||c>'') {if(c=='-') flag=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-,c=getchar();return x*flag;
}
int a[MAXN];
struct Q
{
int opt,l,r,x,f;
}qs[MAXN];
int flagxd=;
struct node
{
int l,r,w,f;
}tree[MAXN];
int buildnow=;
inline void update(int k)
{
tree[k].w=max(tree[ls].w,tree[rs].w);
}
int down(int k)
{
tree[ls].w+=tree[k].f;
tree[rs].w+=tree[k].f;
tree[ls].f+=tree[k].f;
tree[rs].f+=tree[k].f;
tree[k].f=;
}
inline void Build_Tree(int ll,int rr,int k)
{
tree[k].l=ll;tree[k].r=rr;
if(ll==rr)
{
tree[k].w=a[++buildnow];
return ;
}
int mid=tree[k].l+tree[k].r>>;
Build_Tree(ll,mid,ls);
Build_Tree(mid+,rr,rs);
update(k);
}
int ans=;
inline void Interval_Max(int ll,int rr,int k)
{
if(ll<=tree[k].l&&tree[k].r<=rr)
{
ans=max(ans,tree[k].w);
return ;
}
if(tree[k].f) down(k);
int mid=tree[k].l+tree[k].r>>;
if(ll<=mid) Interval_Max(ll,rr,ls);
if(rr>mid) Interval_Max(ll,rr,rs);
update(k);
}
inline void Interval_Add(int ll,int rr,int val,int k)
{
if(ll<=tree[k].l&&tree[k].r<=rr)
{
tree[k].w+=val;
tree[k].f+=val;
return ;
}
if(tree[k].f) down(k);
int mid=tree[k].l+tree[k].r>>;
if(ll<=mid) Interval_Add(ll,rr,val,ls);
if(rr>mid) Interval_Add(ll,rr,val,rs);
update(k);
}
int main()
{
//freopen("noname.in","r",stdin);
// freopen("noname.out","w",stdout);
int n=read(),m=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=m;i++)
{
qs[i].opt=read(),qs[i].l=read(),qs[i].r=read(),qs[i].x=read();
if(qs[i].opt==&&qs[i].x>) flagxd=;
}
if(flagxd)
{
Build_Tree(,n,);
for(int i=;i<=m;i++)
{
if(qs[i].opt==)
{
ans=;
Interval_Max(qs[i].l,qs[i].r,);
printf("%d\n",ans);
}
else
Interval_Add(qs[i].l,qs[i].r,qs[i].x,);
}
}
else
{
for(int i=;i<=m;i++)
{
int l=qs[i].l,r=qs[i].r,x=qs[i].x;
if(qs[i].opt==)
{
priority_queue<int>q;
for(int i=l;i<=r;i++) q.push(a[i]);
if(x>(r-l+)||x==)
{
printf("-1\n");
}
else
{
int now=;
while(now!=x)
q.pop(),now++;
printf("%d\n",q.top());
} }
else
{
for(int i=l;i<=r;i++)
a[i]+=x;
}
}
}
return ;
}
50分暴力
正解:
30分:暴力
另外20分:线段树
再另外20分:主席树||莫队+堆
100分:
线段树
$k<=10$
维护区间前10大的数
每一个区间的前十大是ls的前十大+rs的前10大
类似于归并排序,双指针法
修改:前十大都加val
一个比较方便的写法:重载运算符
总结
这一场考的还算不错 ,起码该拿的分都拿到了。
希望自己调整好心态,稳稳当当的走下去,直到11.12
---恢复内容结束---
T1
n,m都是奇数,后手胜
否则先手胜
T2
20分k==1
最高位异或==1
假设最大的数只有4位
把所有数遍历一边,看一下第四位是0还是1
考虑分治,对于已经确定的高位,在能选择的区间中观察低一位的能否成为1
最长区间为n
复杂度$O(31*n)$
20分不超过1023
记录0-1023的每个数有多少个
每次暴力枚举
$cnt[a^b]+=cnt[a]*cnt[b]$
正解:
01 trie树
先算第k大是啥,再把比他大的加起来
考虑如何求k->二分
如何求比k大的数:
枚举一个i,那么问题就转化为求有多少个j使得a[i]^a[j]>v(二分的值)
用trie树,从最高位开始枚举
看tire树的右儿子(1)有多少个节点
T3
30分:暴力
另外20分:线段树
再另外20分:主席树||莫队+堆
100分:
线段树
$k<=10$
维护区间前10大的数
每一个区间的前十大是ls的前十大+rs的前10大
类似于归并排序,双指针法
修改:前十大都加val
一个比较方便的写法:重载运算符
Day3上午解题报告的更多相关文章
- Day1上午解题报告
预计分数:100+60+0=160 实际分数:100+30+20=150 T1立方数(cubic) 题目描述 LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数 ...
- Day2上午解题报告
预计分数:100+0+60=160 实际分数:100+0+60=160 mmpT1数据错了... T1遭遇 题目描述 你是能看到第一题的 friends呢. —— hja ?座楼房,立于城中 . 第? ...
- Day3下午解题报告
预计分数:20+40+30=90 实际分数:40+90+60=190 再次人品爆发&&手感爆发&&智商爆发 谁能告诉我为什么T1数据这么水.. 谁能告诉我为什么T2数据 ...
- Day5上午解题报告
预计分数:100+40+30=170 实际假分数:0+0+0=0 CE*3 实际真分数:60+50+0=110 老师没把我的程序放的文件夹里面,于是..... T1 https://www.luogu ...
- Day4上午解题报告
预计分数:50 +0+0=50 实际分数:50+0+10=60 毒瘤出题人,T3不给暴力分 (*  ̄︿ ̄) T1 https://www.luogu.org/problem/show?pid=T155 ...
- 夏令营提高班上午上机测试 Day 4 解题报告
我要是没记错的话,今天的题难度算挺适中的. *标程来自高天宇哥哥 T1:小G的字符串 题目描述 有一天,小 L 给小 G 出了这样一道题:生成一个长度为 n 的.全由小写英文字母构成的字符串,只能使用 ...
- Codeforces Round #382 (Div. 2) 解题报告
CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...
- 【LeetCode】306. Additive Number 解题报告(Python)
[LeetCode]306. Additive Number 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
随机推荐
- 国庆 day 6 上午
1. 角谷猜想(kakutani.pas/c/cpp)(kakutani.in/out)时间限制:1s/空间限制:256M[题目描述] 某个名字末尾是 654321 的小 A 同学是个大家眼中公认的学 ...
- Light OJ 1341 Aladdin and the Flying Carpet
题意:求大于b的a的因数对有几组.例10 2结果为{2,5},12 2结果为{2,6}{3,4}-----不反复 解一:分解质因数+DFS #include <iostream> #in ...
- vim 脚本之快速打印log
" zsl_log.vim " Version: 1.0 if exists("g:zsl_loaded_log") || &cp || v:versi ...
- lightoj--1043-- Triangle Partitioning (水题)
Triangle Partitioning Time Limit: 500MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu S ...
- 《读书报告 – Elasticsearch入门 》----Part II 深入搜索(2)
第十三章 全文检索 这一章开始介绍 全文检索 :怎样对全文字段(full-text fields)进行检索以找到相关度最高的文档. 全文检索最重要的两个方面是: 相关度(Relevance) 根据文档 ...
- C# 利用反射和特性 来做一些事情
特性代码: [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public clas ...
- Asp.Net碎知识
在aspx页面 获取值: UserModel user=new UserModel();实例化 user.Address=context["txtAddress"]; 如果前台不需 ...
- Lightroom 学习笔记
16.8.28 白平衡: 夕阳照片,色温高大
- 51nod 最大子矩阵和
一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值. 我们可以降维,枚举矩形的长,然后算出一个一维数组,然后就转化成了最大字段和问题 #include< ...
- 【Codeforces Round #459 (Div. 2) A】Eleven
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 这个数列增长很快的. 直接暴力模拟看看是不是它的一项就好了 [代码] #include <bits/stdc++.h> ...