称区间$[i,j]$为普通区间,当且仅当$j-i\ge 3$​​​且其操作两次内不会变为给定区间

结论:若$[i,j]$为普通区间,则$[i,j]$和$[i+1,j-1]$​​​​​​​​​​的状态(是否先手必胜)相同

(关于这个结论的正确性,不难分类讨论得到)

由此,对于普通区间不断缩小使其变为非普通区间,而非普通区间暴力枚举其变化,直至其长度为1或变为普通区间,显然这类区间至多只有$o(n)$个,因此记忆化后总复杂度也为$o(n)$

综上,只需要能快速实现缩小的过程即可,注意到和是相同的,以和为第一关键字,左端点为第二关键字在所有第2类的非普通区间中二分即可

(暴力的过程中判定区间是否为特殊区间也可以二分)

最终,总复杂度为$o((n+q)\log n)$​,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 600005
4 int t,n,m,q,l,r,ans[N];
5 struct Data{
6 int l,r,p;
7 bool operator < (const Data &k)const{
8 return (l+r<k.l+k.r)||(l+r==k.l+k.r)&&(l<k.l);
9 }
10 bool operator == (const Data &k)const{
11 return (l==k.l)&&(r==k.r);
12 }
13 bool operator != (const Data &k)const{
14 return (l!=k.l)||(r!=k.r);
15 }
16 }a[N],b[N];
17 int find(int l,int r){
18 Data o=Data{l,r,0};
19 int p=lower_bound(b+1,b+m+1,o)-b;
20 if ((p>m)||(b[p]!=o))return -1;
21 return p;
22 }
23 int get_nex(int l,int r){
24 Data o=Data{l,r,0};
25 int p=lower_bound(b+1,b+m+1,o)-b;
26 if ((p<=m)&&(o.l+o.r==b[p].l+b[p].r))return b[p].l-o.l;
27 return (r-l-1>>1);
28 }
29 bool calc(int l,int r){
30 int p=find(l,r);
31 if (p>0){
32 if (b[p].p>=0)return b[p].p;
33 if (ans[p]>=0)return ans[p];
34 }
35 if (l==r)return 0;
36 if ((r-l>=3)&&(p<0)){
37 p=get_nex(l,r);
38 return calc(l+p,r-p);
39 }
40 int s=((calc(l,r-1)&calc(l+1,r))^1);
41 if (p>0)ans[p]=s;
42 return s;
43 }
44 int main(){
45 scanf("%d",&t);
46 while (t--){
47 scanf("%d%d",&n,&q);
48 for(int i=1;i<=n;i++){
49 scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].p);
50 a[i+n]=Data{a[i].l-1,a[i].r,-1};
51 a[i+n*2]=Data{a[i].l-2,a[i].r,-1};
52 a[i+n*3]=Data{a[i].l,a[i].r+1,-1};
53 a[i+n*4]=Data{a[i].l,a[i].r+2,-1};
54 a[i+n*5]=Data{a[i].l-1,a[i].r+1,-1};
55 }
56 sort(a+1,a+n*6+1);
57 m=0;
58 for(int i=1;i<=n*6;i++){
59 if ((a[i].l<=0)||(a[i].r>1e9))continue;
60 if ((!m)||(b[m]!=a[i]))b[++m]=a[i];
61 else{
62 if (b[m].p<0)b[m].p=a[i].p;
63 }
64 }
65 for(int i=1;i<=m;i++)ans[i]=-1;
66 for(int i=1;i<=q;i++){
67 scanf("%d%d",&l,&r);
68 printf("%d",calc(l,r));
69 }
70 printf("\n");
71 }
72 return 0;
73 }

[hdu7035]Game的更多相关文章

随机推荐

  1. python-docx 页面设置

    初识word文档-节-的概念 编辑一篇word文档,往往首先从页面设置开始,从下图可以看出,页面设置常操作的有页边距.纸张方向.纸张大小4个,而在word中是以节(section)来分大的块,每一节的 ...

  2. PowerDotNet平台化软件架构设计与实现系列(02):数据库管理平台

    为了DB复用和简化管理,我们对常见应用依赖的DB模块进行更高级的提取和抽象. 虽然一些ORM可以简化DB开发,但是我们还是需要进行改进和优化,否则应用越多,后期管理运维越混乱. 根据常见开发需要,数据 ...

  3. 基于注解实现jackson动态JsonProperty

    基于注解实现jackson动态JsonProperty @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,但是值是固定的 ...

  4. 2020.1.30--vj补题

    C - C CodeForces - 991C 题目内容: After passing a test, Vasya got himself a box of n candies. He decided ...

  5. C 标准库函数手册摘要

    <stdlib.h> int abs( int value ); long int labs( long int value ); 返回参数的绝对值 int rand( void ); v ...

  6. [no code][scrum meeting] Alpha 13

    项目 内容 会议时间 2020-04-21 会议主题 OCR技术对接会议 会议时长 45min 参会人员 全体成员 $( "#cnblogs_post_body" ).catalo ...

  7. gdal注册nsdtfDEM格式驱动配置

    一.关于nsdtf格式 *.dem是一种比较常见的DEM数据格式,其有两种文件组织方式,即NSDTF-DEM和USGS-DEM . NSDTF-DEM NSDTF-DEM是一种明码的中国国家标准空间数 ...

  8. 【做题记录】[NOIP2011 提高组] 观光公交

    P1315 [NOIP2011 提高组] 观光公交 我们想在 \(k\) 次加速每一次都取当前最优的方案加速. 考虑怎样计算对于每一条边如果在当前情况下使用加速器能够使答案减少的大小. 如果当前到达某 ...

  9. 矩阵中的路径 牛客网 剑指Offer

    矩阵中的路径 牛客网 剑指Offer 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下 ...

  10. Educational Codeforces Round 113 (Rated for Div. 2)题解

    \(A,B,C\)顺利签到,还是在\(D\)上面卡住了,之后在睡前还是想出来了,看来还是自己的思维不够敏捷和成熟... D. Inconvenient Pairs 简化题意,在一个直角坐标系中,有一些 ...