[hdu7035]Game
称区间$[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的更多相关文章
随机推荐
- redux搭配react-redux进行跨组件通信开发
Redux API 作用 createStore 用于创建一个store对象 bindActionCreators 用于简化操作,不用开发者手动触发dispatch React-redux API 作 ...
- 日常学习用到的Git指令
Git 常用Git指令 (本地) git init - 将文件夹初始化为Git仓库 git add - 将工作区的指定文件放入暂存区 git status - 查看工作区和暂存区的状态 git com ...
- 订单峰值激增 230%,Serverless 如何为世纪联华降本超 40%?|双11 云原生实践
作者 | 朱鹏 导读:2020 年 双11,世纪联华基于阿里云函数计算 (FC) 弹性扩容,应用于大促会场 SSR.线上商品秒杀.优惠券定点发放.行业导购.数据中台计算等多个场景,业务峰值 QPS 较 ...
- Hive中的4种Join方式
common join 普通join,性能较差,存在Shuffle map join 适用情况:大表join小表时,做不等值join 原理:将小表数据广播到各个节点,存储在内存中,在map阶段直接jo ...
- scala基础篇 使用getter和setter方法而不使用public的情形
主要是基于2种情形 1) 提供读只取/只写入方法,不能随意读写 2)做赋值时变量控制,比如设定值的区间范围等 例子: object test{ def main(args: Array[String] ...
- JDK中的SPI机制
前言 最近学习类加载的过程中,了解到JDK提供给我们的一个可扩展的接口:java.util.ServiceLoader, 之前自己不了解这个机制,甚是惭愧... 什么是SPI SPI全称为(Servi ...
- Mybatis 动态Sql练习
建表 CREATE TABLE `student` ( `s_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT ...
- 什么是产品待办列表?(What is Product Backlog)
正如scrum指南中所描述的,产品待办事项列表是一个紧急而有序的列表,其中列出了改进产品所需的内容.它是scrum团队承担的工作的唯一来源. 在sprint计划 (Sprint Planning)活动 ...
- kivy画板
from kivy.app import App from kivy.graphics import Line, Color # 引入绘图线条,颜色 from kivy.uix.widget impo ...
- simulate_click
#!/bin/bashlet actual_x=104+144*$[$2-1]let actual_y=945+144*$[$1-1]adb shell input tap ${actual_x} $ ...