称区间$[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. spring 创建Bean最全实现方法

    创建bean方式,spring创建bean的方式包含:自动注入方式和人工注入方式.分别为:1)xml 配置化方式  2)@bean注解注入方式3)@Component方式 4)接口注入方式 5)imp ...

  2. Conversion Tools(转换工具)

    转换工具 1.Excel # Process: Excel 转表 arcpy.ExcelToTable_conversion("", 输出表, "") # Pr ...

  3. selenium 4.0 发布

    我们非常高兴地宣布Selenium 4的发布.这适用于Java..net.Python.Ruby和Javascript.你可以从你最喜欢的包管理器或GitHub下载它! https://github. ...

  4. Java(2)详解注释&关键字&常量&变量&标识符

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201497.html 博客主页:https://www.cnblogs.com/testero ...

  5. 初学python写个自娱自乐的小游戏

    一.摘要 当编写完后的代码执行第一次后达到了目标的预期效果,内心有些许满足,但是当突发情况产生后,程序便不能正常运行,于是准备从简单的版本开始出发,综合考虑使用者的需求,和使用过程中会遇到的问题,一步 ...

  6. MongoDB中如何优雅地删除大量数据

    删除大量数据,无论是在哪种数据库中,都是一个普遍性的需求.除了正常的业务需求,我们需要通过这种方式来为数据库"瘦身". 为什么要"瘦身"呢? 表的数据量到达一定 ...

  7. 【UE4 C++】 Datatable 读写、导入导出 CSV/Json

    Datatable 读取行数据 1. 创建结构体 继承自 FTableRowBase USTRUCT(BlueprintType) struct FSimpleStruct :public FTabl ...

  8. Java:Iterator接口与fail-fast小记

    Java:Iterator接口与fail-fast小记 对 Java 中的 Iterator接口 和 fail-fast,做一个微不足道的小小小小记 Iterator Iterator接口 Itera ...

  9. [技术博客]大闸蟹的技术博客,通过gitlab api进行用户批量创建

    技术博客--通过gitlab api批量注册用户 gitlab登录界面本身提供了register功能,但需要手工一个个添加,对于一次性会添加整个班级的学生的软工平台来说并不科学合理.使用gitlab ...

  10. Noip模拟39 2021.8.14

    T1 打地鼠 都切掉了的简单题 1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 con ...