玲珑杯#3 G 1043 - G. Quailty and Square Counter【线段树-卡常数】
2016-09-30 18:19
387 查看
题目链接:1043 - G. Quailty and Square Counter
首先,x向x^2%2017建边,跑一跑找找规律,能发现环套树一共有14个,每个的环最大6,且在环上的点一共64个,且不在环上的点到环的常数最多5。知道这样的性质后,就简单了,区间平方直接暴力,区间赋值直接搞,暴力的话到某个区间为相同数时停止。
其实上面都不是重点,大家都会,卡常才是最重要的,我从本地43s卡到11.6s,交上去跑了7s。
my code:
首先,x向x^2%2017建边,跑一跑找找规律,能发现环套树一共有14个,每个的环最大6,且在环上的点一共64个,且不在环上的点到环的常数最多5。知道这样的性质后,就简单了,区间平方直接暴力,区间赋值直接搞,暴力的话到某个区间为相同数时停止。
其实上面都不是重点,大家都会,卡常才是最重要的,我从本地43s卡到11.6s,交上去跑了7s。
my code:
#include <bits/stdc++.h> using namespace std ; typedef long long LL ; #define clr( a , x ) memset ( a , x , sizeof a ) #define root 1 , 1 , n #define ls o << 1 #define rs o << 1 | 1 #define lson ls , l , m #define rson rs , m + 1 , r const int MAXN = 100005 ; const int mod = 2017 ; int be[mod][2] , step[mod][10] , len[mod] , vis[mod] , S[mod] , top , cas ; unsigned long long T[MAXN * 3] , all[15] , res ; int same[MAXN * 3] , shift[MAXN * 3] , in[MAXN * 3] , setv[MAXN * 3] ; bitset < 2017 > G[MAXN * 3] , ans ; int n , m ; void preprocess () { cas = 0 ; for ( int i = 0 ; i < mod ; ++ i ) { step[i][0] = i ; for ( int j = 1 ; j < 10 ; ++ j ) { step[i][j] = step[i][j - 1] * step[i][j - 1] % mod ; } } int now = 0 ; for ( int i = 0 ; i < mod ; ++ i ) if ( !vis[i] ) { int x = i , ok = 1 ; vis[x] = -1 ; top = 0 ; S[top ++] = x ; while ( 1 ) { x = x * x % mod ; if ( !vis[x] ) { vis[x] = -1 ; S[top ++] = x ; } else if ( vis[x] == 1 ) { ok = 0 ; break ; } else { ok = 1 ; break ; } } if ( ok == 1 ) { for ( int j = 0 ; j < top ; ++ j ) { if ( S[j] == x ) { len[++ cas] = top - j ; all[cas] = 0 ; for ( int k = j ; k < top ; ++ k ) { all[cas] |= 1ULL << now ; be[S[k]][0] = cas ; be[S[k]][1] = now ++ ; } break ; } } } for ( int j = 0 ; j < top ; ++ j ) { vis[S[j]] = 1 ; } } } void up ( int o ) { int tmp = in[o] ; T[o] = T[ls] | T[rs] ; in[o] = in[ls] & in[rs] ; //G[o] = G[ls] | G[rs] ; if ( same[ls] == same[rs] ) same[o] = same[ls] ; else same[o] = -1 ; if ( tmp && in[o] ) return ; if ( in[o] ) G[o].reset () ; else if ( in[ls] ) G[o] = G[rs] ; else if ( in[rs] ) G[o] = G[ls] ; else { G[o] = G[ls] ; if ( same[o] == -1 ) G[o] |= G[rs] ; } } void Shift ( int o , int s ) { int &x = same[o] ; shift[o] += s ; if ( !~x ) { unsigned long long t = 0 ; for ( int i = 1 ; i <= 14 ; ++ i ) { unsigned long long tmp = all[i] & T[o] ; if ( !tmp ) continue ; int a = s % len[i] ; int b = len[i] - a ; t |= ( ( tmp << a ) | ( tmp >> b ) ) & all[i] ; } T[o] = t ; } else { //s step if ( s <= 5 ) { if ( be[x][0] ) T[o] = 0 ; else G[o][x] = 0 ; x = step[x][s] ; if ( be[x][0] ) T[o] = 1ULL << be[x][1] , in[o] = 1 ; else G[o][x] = 1 , in[o] = 0 ; } else { if ( be[x][0] ) T[o] = 0 ; else G[o][x] = 0 ; x = step[x][6] ; s -= 6 ; s %= len[be[x][0]] ; x = step[x][s] ; if ( be[x][0] ) T[o] = 1ULL << be[x][1] , in[o] = 1 ; else G[o][x] = 1 , in[o] = 0 ; } } } void Same ( int o , int x ) { T[o] = 0 ; shift[o] = 0 ; if ( !in[o] ) { if ( ~same[o] ) { if ( x != same[o] ) G[o][same[o]] = 0 ; } else G[o].reset () ; } setv[o] = same[o] = x ; if ( be[x][0] ) T[o] = 1ULL << be[x][1] , in[o] = 1 ; else G[o][x] = 1 , in[o] = 0 ; } void down ( int o ) { if ( ~setv[o] ) { Same ( ls , setv[o] ) ; Same ( rs , setv[o] ) ; setv[o] = -1 ; } if ( shift[o] ) { Shift ( ls , shift[o] ) ; Shift ( rs , shift[o] ) ; shift[o] = 0 ; } } void update ( int L , int R , int x , int o , int l , int r ) { if ( L <= l && r <= R ) { if ( ~x ) Same ( o , x ) ; else { if ( l == r ) Shift ( o , 1 ) ; else { if ( in[o] || ~same[o] ) Shift ( o , 1 ) ; else { down ( o ) ; int m = l + r >> 1 ; update ( L , R , x , lson ) ; update ( L , R , x , rson ) ; up ( o ) ; } } } return ; } down ( o ) ; int m = l + r >> 1 ; if ( L <= m ) update ( L , R , x , lson ) ; if ( m < R ) update ( L , R , x , rson ) ; up ( o ) ; } void query ( int L , int R , int o , int l , int r ) { if ( L <= l && r <= R ) { res |= T[o] ; if ( !in[o] ) ans |= G[o] ; return ; } down ( o ) ; int m = l + r >> 1 ; if ( L <= m ) query ( L , R , lson ) ; if ( m < R ) query ( L , R , rson ) ; } void build ( int o , int l , int r ) { setv[o] = -1 ; shift[o] = 0 ; if ( l == r ) { int x ; scanf ( "%d" , &x ) ; G[o].reset () ; T[o] = 0 ; if ( be[x][0] ) T[o] = 1ULL << be[x][1] , in[o] = 1 ; else G[o][x] = 1 , in[o] = 0 ; same[o] = x ; return ; } int m = l + r >> 1 ; build ( lson ) ; build ( rson ) ; up ( o ) ; } void show ( int o , int l , int r ) { if ( l == r ) { //printf ( "%d%c" , same[o] , l == n ? '\n' : ' ' ) ; return ; } int m = l + r >> 1 ; down ( o ) ; show ( lson ) ; show ( rson ) ; } void solve ( int T ) { scanf ( "%d%d" , &n , &m ) ; build ( root ) ; for ( int i = 0 ; i < m ; ++ i ) { int op , l , r , x ; scanf ( "%d%d%d" , &op , &l , &r ) ; if ( op == 1 ) update ( l , r , -1 , root ) ; else if ( op == 2 ) { scanf ( "%d" , &x ) ; update ( l , r , x , root ) ; } else { res = 0 ; ans.reset () ; //show ( root ) ; query ( l , r , root ) ; int num = ans.count () + __builtin_popcountll ( res ) ; printf ( "%d\n" , num ) ; } } } int main () { preprocess () ; int T ; //freopen ( "H.in" , "r" , stdin ) ; //freopen ( "h1.txt" , "w" , stdout ) ; scanf ( "%d" , &T ) ; for ( int i = 1 ; i <= T ; ++ i ) { solve ( i ) ; } //printf ( "%.5f\n" , ( double ) clock () / CLOCKS_PER_SEC ) ; return 0 ; }
相关文章推荐
- codeforce 914-D. Bash and a Tough Math Puzzle(线段树)
- LeeCode-Sqrt(x)Implement int sqrt(int x). Compute and return the square root of x.
- codeforces 259-B. Little Elephant and Magic Square(数学)
- [线段树][矩乘][DP]Codeforces Round 573D && RussianCodeCup Thanks-Round .Bear and Cavalry
- HDU 3911 Black And White(线段树区间合并)
- HUD 3911 Black And White 线段树 区间更新 + 区间合并
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp
- HDU 4614 Vases and Flowers [二分 + 线段树]
- codeforces 272C. Dima and Staircase(线段树)
- 【Codechef】【Chef and Graph Queries】Lct 可持久化线段树
- HDU-4614 Vases and Flowers (线段树区间更新)
- hdu 4614 Vases and Flowers (线段树打标记)
- R2D2 and Droid Army(多棵线段树)
- Codeforces Round #381 (Div. 2) D. Alyona and a tree dfs+二分+线段树延迟操作、树形化线性
- Codeforces Round #369 (Div. 2) B. Chris and Magic Square (暴力)
- hdu 5068 Harry And Math Teacher 线段树
- hhuoj Mouse and Parenthesis 线段树求局部最小值 TWT Tokyo Olymipic 2COMBO -1 未完待续
- 玲珑杯 1117 - RE:从零开始的异世界生活(线段树)
- Codeforces 716C C. Plus and Square Root
- hdu 1823 Luck and Love (二维树套树线段树)