# [USACO13JAN]Cow Lineup

## Code

#include <bits/stdc++.h>
using namespace std ;
void Read ( int &x, char c = getchar() ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
}
const int maxn = 1e5+5 ;
int n, m, k, a[maxn], b[maxn], size[maxn], Head[maxn], Next[maxn], Pre[maxn] ;
int tot, tree[maxn*60], ch[maxn*60][2], rt[maxn] ;
void push_up ( int x ) {
tree[x] = 0 ;
if (ch[x][0]) tree[x] += tree[ch[x][0]] ;
if (ch[x][1]) tree[x] += tree[ch[x][1]] ;
}
int create ( int l, int r, int v ) {
int x = ++tot, mid = (l+r)>>1 ;
if (l == r) {
++tree[x] ;
return x ;
}
if (v <= mid) ch[x][0] = create(l, mid, v) ;
else ch[x][1] = create(mid+1, r, v) ;
push_up(x) ;
return x ;
}
int insert ( int h, int l, int r, int v, int c ) {
int x = ++tot, mid = (l+r)>>1 ;
if (l == r) {
if (h) tree[x] = tree[h] ;
tree[x] += c ;
return x ;
}
if (v <= mid) {
ch[x][0] = insert(ch[h][0], l, mid, v, c) ;
if (h) ch[x][1] = ch[h][1] ;
} else {
ch[x][0] = ch[h][0] ;
if (h) ch[x][1] = insert(ch[h][1], mid+1, r, v, c) ;
}
push_up(x) ;
return x ;
}
int query ( int h, int l, int r, int x, int y ) {
if (x <= l && r <= y) return tree[h] ;
int mid = (l+r)>>1 ;
if (y <= mid) return query(ch[h][0], l, mid, x, y) ;
else if (x > mid) return query(ch[h][1], mid+1, r, x, y) ;
return query(ch[h][0], l, mid, x, mid)+query(ch[h][1], mid+1, r, mid+1, y) ;
}
bool calc ( int x, int value ) {
int rec, l, r ;
for ( r = l = Head[x] ; value > 1 ; r = Next[r], value -- ) ;
if (r == 0) return 0 ;
for ( ; l && r ; l = Next[l], r = Next[r] ) {
rec = query(rt[r], 1, n, l, r) ;
if (rec <= m+1) return 1 ;
}
return 0 ;
}
bool judge ( int value ) {
int i ;
for ( i = 1 ; i <= n ; i ++ )
if (size[i] >= value && calc(i, value)) return 1 ;
return 0 ;
}
int main() {

int i ;
for ( i = 1 ; i <= n ; i ++ ) Read(a[i]), b[i] = a[i] ;
sort(b+1, b+n+1) ;
k = unique(b+1, b+n+1)-b-1 ;
for ( i = 1 ; i <= n ; i ++ )
++size[a[i] = lower_bound(b+1, b+k+1, a[i])-b] ;

for ( i = n ; i ; i -- )
}

rt[1] = create(1, n, 1) ;
for ( i = 2 ; i <= n ; i ++ ) {
if (Pre[i]) {
rt[i] = insert(rt[i - 1], 1, n, Pre[i], -1) ;
rt[i] = insert(rt[i], 1, n, i, 1) ;
} else rt[i] = insert(rt[i - 1], 1, n, i, 1) ;
}
int l, r, mid, rec = 0 ;
l = 1, r = n ;
while (l <= r) {
mid = (l+r)>>1 ;
if (judge(mid)) rec = mid, l = mid+1 ;
else r = mid-1 ;
}
printf ( "%d\n", rec ) ;
return 0 ;
}

# [SDOI2009]HH的项链

## Code

#include <bits/stdc++.h>
using namespace std ;
void Read ( int &x, char c = getchar() ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
}
const int maxn = 5e4+5 ;
int n, m, a[maxn], b[maxn], pre[maxn] ;
int tree[maxn*60], ch[maxn*60][2], rt[maxn], tot ;
void push_up ( int x ) {
tree[x] = 0 ;
if (ch[x][0]) tree[x] += tree[ch[x][0]] ;
if (ch[x][1]) tree[x] += tree[ch[x][1]] ;
}
int create ( int l, int r, int v ) {
int x = ++tot, mid = (l+r)>>1 ;
if (l == r) {
tree[x] ++ ;
return x ;
}
if (v <= mid) ch[x][0] = create(l, mid, v) ;
else ch[x][1] = create(mid+1, r, v) ;
push_up(x) ;
return x ;
}
int insert ( int h, int l, int r, int v, int value ) {
int x = ++tot, mid = (l+r)>>1 ;
if (l == r) {
tree[x] = tree[h] ;
tree[x] += value ;
return x ;
}
if (v <= mid) {
ch[x][0] = insert(ch[h][0], l, mid, v, value) ;
ch[x][1] = ch[h][1] ;
} else {
ch[x][0] = ch[h][0] ;
ch[x][1] = insert(ch[h][1], mid+1, r, v, value) ;
}
push_up(x) ;
return x ;
}
int query ( int h, int l, int r, int x, int y ) {
if (h == 0) return 0 ;
if (x <= l && r <= y) return tree[h] ;
int mid = (l+r)>>1 ;
if (y <= mid) return query(ch[h][0], l, mid, x, y) ;
else if (x > mid) return query(ch[h][1], mid+1, r, x, y) ;
return query(ch[h][0], l, mid, x, mid)+query(ch[h][1], mid+1, r, mid+1, y) ;
}
void check ( int x, int l, int r ) {
printf ( "%d [%d,%d]=%d\n", x, l, r, tree[x] ) ;
int mid = (l+r)>>1 ;
if (ch[x][0]) check(ch[x][0], l, mid) ;
if (ch[x][1]) check(ch[x][1], mid+1, r) ;
}
int main() {
int i, l, r, _ ;
for ( i = 1 ; i <= n ; i ++ ) Read(a[i]), b[i] = a[i] ;
sort(b+1, b+n+1) ;
m = unique(b+1, b+n+1)-b-1 ;
for ( i = 1 ; i <= n ; i ++ )
a[i] = lower_bound(b+1, b+m+1, a[i])-b ;
memset ( b, 0, sizeof b ) ;
for ( i = 1 ; i <= n ; i ++ )
pre[i] = b[a[i]], b[a[i]] = i ;
rt[1] = create(1, n, 1) ;
for ( i = 2 ; i <= n ; i ++ ) {
if (pre[i]) {
rt[i] = insert(rt[i - 1], 1, n, pre[i], -1) ;
rt[i] = insert(rt[i], 1, n, i, 1) ;
} else rt[i] = insert(rt[i - 1], 1, n, i, 1) ;
}
while (_--) {
printf ( "%d\n", query(rt[r], 1, n, l, r) ) ;
}
return 0 ;
}

# [SCOI2008]奖励关

## Description

k100,N15$k \le 100, N \le 15$

## Solution

f[i][x]$f[i][x]$代表当前是第i$i$轮，已经获取过的宝物集合为x$x$

## Code

#include <bits/stdc++.h>
using namespace std ;
int n, m, c[105], p[105] ;
double f[105][(1<<15)+5] ;
int main() {
int i, j, k, s, S ;
scanf ( "%d%d", &m, &n ) ;
S = (1<<n)-1 ;
for ( i = 1 ; i <= n ; i ++ ) {
scanf ( "%d", c+i ) ;
while (scanf("%d",&k) && k)
p[i] |= 1<<(k-1) ;
}
for ( i = m-1 ; i >= 0 ; i -- ) {
for ( s = 0 ; s <= S ; s ++ )
for ( j = 1 ; j <= n ; j ++ )
if ( (p[j]&s) == p[j] )
f[i][s] += max(f[i + 1][s]/n, (f[i + 1][s|(1<<(j-1))]+c[j])*1.0/n) ;
else f[i][s] += f[i + 1][s]/n ;
}
printf ( "%.6lf\n", f[0][0] ) ;
return 0 ;
}

# [AHOI2009]中国象棋

## Solution

f[i][a][b]$f[i][a][b]$代表前i$i$行，有a$a$列放了0$0$个炮，有b$b$列放了1$1$个炮，那么有Mab$M-a-b$列放了2$2$个炮。

## Code

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
const int maxn = 105, modd = 9999973 ;
int n, m ;
LL f[maxn][maxn][maxn] ;
LL c ( int x ) { return ((LL)x*(x-1)/2)%modd ; }
int main() {
int i, a, b ;
scanf ( "%d%d", &n, &m ) ;
f[0][m][0] = 1 ;
for ( i = 0 ; i < n ; i ++ ) {
for ( a = 0 ; a <= m ; a ++ )
for ( b = 0 ; a+b <= m ; b ++ ) {
(f[i + 1][a][b] += f[i][a][b]) %= modd ;
if (a >= 1) (f[i + 1][a - 1][b + 1] += a*f[i][a][b]%modd) %= modd ;
if (b >= 1) (f[i + 1][a][b - 1] += b*f[i][a][b]%modd) %= modd ;
if (a >= 1) (f[i + 1][a - 1][b] += a*b*f[i][a][b]%modd) %= modd ;
if (a >= 2) (f[i + 1][a - 2][b + 2] += c(a)*f[i][a][b]%modd) %= modd ;
if (b >= 2) (f[i + 1][a][b - 2] += c(b)*f[i][a][b]%modd) %= modd ;
}
}
LL ans = 0 ;
for ( a = 0 ; a <= m ; a ++ )
for ( b = 0 ; a+b <= m ; b ++ )
(ans += f[n][a][b]) %= modd ;
printf ( "%lld\n", ans ) ;
return 0 ;
}

# [SCOI2005]最大子矩阵

## Solution

m$m$分情况讨论。
m=1$m=1$。暴力DP。随便搞。

m=2$m=2$

f[a][b][t]$f[a][b][t]$表示第1列最后一个选取的位置是a，第2列最后一个选取的位置是b，一共选了t个矩形。讨论当前新选一个矩形是完全处于第1列还是完全处于第2列还是宽为2。
DP转移的时候枚举前一个矩形的结尾，当前矩形的开头用RMQ在前缀和上查询。

## Code

#include <bits/stdc++.h>
using namespace std ;
const int maxn = 105, zhf = 1e7 ;
int n, m, k, a[maxn][3], g[maxn][10][3], f[maxn][maxn][30], dp[maxn][30] ;
void init ( int t ) {
int i, j ;
for ( i = 1 ; i <= n ; i ++ )
g[i][0][t] = (a[i][t] += a[i - 1][t]) ;
for ( j = 1 ; j < 10 ; j ++ )
for ( i = 1 ; i+(1<<j)-1 <= n ; i ++ )
g[i][j][t] = min(g[i][j-1][t], g[i+(1<<(j-1))][j-1][t]) ;
}
int query ( int l, int r, int t ) {
if (l > r) return zhf ;
int len = floor(log(r-l+1)/log(2.0)) ;
return min(g[l][len][t], g[r-(1<<len)+1][len][t]) ;
}
int check_max ( int &x, int y ) { return x = x>y ? x:y ; }
void solve1() {
int i, j, l ;
for ( i = 1 ; i <= n ; i ++ )
scanf ( "%d", &a[i][0] ) ;
init(0) ;
for ( i = 1 ; i <= n ; i ++ ) {
for ( j = 0 ; j < i ; j ++ )
for ( l = 1 ; l <= k ; l ++ ) {
check_max(dp[i][l], dp[j][l-1] + a[i][0] - query(j,i-1,0)) ;
}
}
int ans = 0 ;
for ( i = 1 ; i <= n ; i ++ )
for ( j = 1 ; j <= k ; j ++ )
check_max(ans, dp[i][j] ) ;
printf ( "%d\n", ans ) ;
}
void solve2() {
register int ans = 0, i, j, l, r, t ;
for ( i = 1 ; i <= n ; i ++ ) {
scanf ( "%d%d", &a[i][0], &a[i][1] ) ;
a[i][2] = a[i][0] + a[i][1] ;
}
init(0) ; init(1) ; init(2) ;
for ( i = 0 ; i <= n ; i ++ )
for ( j = 0 ; j <= n ; j ++ ) {
check_max(f[i][j][(i>=1)+(j>=1)], a[i][0]+a[j][1]) ;
for ( t = 1 ; t <= k ; t ++ ) {
for ( l = 0 ; l < i ; l ++ )
check_max(f[i][j][t], f[l][j][t-1] + a[i][0] - query(l,i-1,0)) ;
for ( l = 0 ; l < j ; l ++ )
check_max(f[i][j][t], f[i][l][t-1] + a[j][1] - query(l,j-1,1)) ;
if (i == j && i) {
for ( l = 0 ; l < i ; l ++ )
for ( r = 0 ; r < i ; r ++ )
check_max(f[i][j][t], f[l][r][t-1] + a[i][2] - query(max(l,r),i-1,2)) ;
}
check_max(ans, f[i][j][t]) ;
}
}
printf ( "%d\n", ans ) ;
}
int main() {
scanf ( "%d%d%d", &n, &m, &k ) ;
if (m == 1) solve1() ;
else solve2() ;
return 0 ;
}

# [SCOI2005]互不侵犯King

## Description

N×N$N \times N$的棋盘里面放K$K$个国王，使他们互不攻击，共有多少种摆放方案。N9$N \le 9$

## Code

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
LL n, m, f[10][520][100], bt[520] ;
bool judge ( LL a, LL b ) {
if (a&b) return 0 ;
a |= b ;
if (a&(a>>1)) return 0 ;
return 1 ;
}
int main() {
LL i, j, s, x, S ;
cin >> n >> m ;
S = (1<<n)-1 ;
for ( s = 0 ; s <= S ; s ++ )
bt[s] = bt[s>>1] + (s&1) ;
memset ( f, 0, sizeof f ) ;
for ( s = 0 ; s <= S ; s ++ )
if (judge(0, s)) f[1][s][bt[s]] = 1 ;
for ( i = 2 ; i <= n ; i ++ )
for ( s = 0 ; s <= S ; s ++ )
for ( x = 0 ; x <= S ; x ++ )
if (judge(s, x)) {
for ( j = bt[s]+bt[x] ; j <= m ; j ++ )
if (f[i - 1][x][j - bt[s]] > 0) f[i][s][j] += f[i - 1][x][j - bt[s]] ;
}
LL ans = 0 ;
for ( s = 0 ; s <= S ; s ++ )
if (f[n][s][m] > 0) ans += f[n][s][m] ;
printf ( "%lld\n", ans ) ;
return 0 ;
}

# [USACO5.1]Musical Themes

## Code

#include <bits/stdc++.h>
using namespace std ;
const int maxn = 2e5+5 ;
int rnk[maxn], s[maxn], n, m, sa[maxn], height[maxn], s1[maxn], s2[maxn], c[maxn], a[maxn] ;
void get_sa() {
int i, p, len ;
int *x = s1, *y = s2 ;
for ( i = 1 ; i <= n ; i ++ ) m = max(m, s[i]) ;
memset ( c, 0, sizeof c ) ;
for ( i = 1 ; i <= n ; i ++ ) c[x[i] = s[i]] ++ ;
for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i - 1] ;
for ( i = n ; i ; i -- ) sa[c[x[i]]--] = i ;

for ( len = 1 ; len < n ; len <<= 1, m = p ) {
p = 0 ;
for ( i = n-len+1 ; i <= n ; i ++ ) y[++p] = i ;
for ( i = 1 ; i <= n ; i ++ )
if (sa[i] > len) y[++p] = sa[i]-len ;

memset ( c, 0, sizeof c ) ;
for ( i = 1 ; i <= n ; i ++ ) c[x[y[i]]] ++ ;
for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i - 1] ;
for ( i = n ; i ; i -- ) sa[c[x[y[i]]]--] = y[i] ;

swap(x, y) ;
p = 1 ;
x[sa[1]] = 1 ;
for ( i = 2 ; i <= n ; i ++ )
if (y[sa[i]]==y[sa[i-1]] && y[sa[i]+len]==y[sa[i-1]+len])
x[sa[i]] = p ;
else x[sa[i]] = ++p ;
if (p >= n) break ;
}
}
void get_height() {
int i, j, k = 0 ;
for ( i = 1 ; i <= n ; i ++ ) rnk[sa[i]] = i ;
for ( i = 1 ; i <= n ; i ++ ) {
if (k) -- k ;
j = sa[rnk[i]-1] ;
while (s[i+k] == s[j+k]) ++ k ;
height[rnk[i]] = k ;
}
}
bool judge ( int len ) {
int i, minn = sa[1], maxx = sa[1] ;
for ( i = 2 ; i <= n ; i ++ )
if (height[i] < len) minn = maxx = sa[i] ;
else {
minn = min(minn, sa[i]) ;
maxx = max(maxx, sa[i]) ;
if (maxx - minn > len) return 1 ;
}
return 0 ;
}
int main() {
int i, l, r, mid, rec ;
scanf ( "%d", &n ) ;
for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d", a+i ) ;
for ( i = 1 ; i <= n ; i ++ ) s[i] = a[i] - a[i - 1] + 100 ;

get_sa() ;
get_height() ;
l = 1, r = n>>1 ;
while (l <= r) {
mid = (l+r)>>1 ;
if (judge(mid)) rec = mid, l = mid+1 ;
else r = mid-1 ;
}
if (rec < 4) rec = 0 ;
else ++ rec ;
printf ( "%d\n", rec ) ;
return 0 ;
}

# [HAOI2008]硬币购物

## Solution

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
void Read ( LL &x, char c = getchar() ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
}
LL n, m, v[5] ;
LL f[100005] ;
void calc ( LL &rec, LL x, LL value ) {
if (x >= 0) rec += f[x]*value ;
}
int main() {
LL i, j, t, rec, a, b, c, d ;
for ( i = 1 ; i < 5 ; i ++ ) Read(v[i]) ;
n = 1e5 ;
f[0] = 1 ;
for ( i = 1 ; i < 5 ; i ++ )
for ( j = v[i] ; j <= n ; j ++ )
f[j] += f[j - v[i]] ;
for ( i = 1 ; i <= m ; i ++ ) {
rec = 0 ;
++ a ; ++ b ; ++ c ; ++ d ;
calc(rec, t, 1) ;

calc(rec, t - a*v[1], -1) ;
calc(rec, t - b*v[2], -1) ;
calc(rec, t - c*v[3], -1) ;
calc(rec, t - d*v[4], -1) ;

calc(rec, t - a*v[1] - b*v[2], 1) ;
calc(rec, t - a*v[1] - c*v[3], 1) ;
calc(rec, t - a*v[1] - d*v[4], 1) ;
calc(rec, t - b*v[2] - c*v[3], 1) ;
calc(rec, t - b*v[2] - d*v[4], 1) ;
calc(rec, t - c*v[3] - d*v[4], 1) ;

calc(rec, t - a*v[1] - b*v[2] - c*v[3], -1) ;
calc(rec, t - a*v[1] - b*v[2] - d*v[4], -1) ;
calc(rec, t - a*v[1] - c*v[3] - d*v[4], -1) ;
calc(rec, t - b*v[2] - c*v[3] - d*v[4], -1) ;

calc(rec, t - a*v[1] - b*v[2] - c*v[3] - d*v[4], 1) ;

printf ( "%lld\n", rec ) ;
}
return 0 ;
}

# [USACO06DEC]Milk Patterns

## Solution

#include <bits/stdc++.h>
using namespace std ;
void Read ( int &x, char c = getchar() ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
}
const int maxn = 2e4+5 ;
int n, m, e, s[maxn], b[maxn], sa[maxn], height[maxn], s1[maxn], s2[maxn], rnk[maxn], c[maxn] ;
void init() {
int i, p, len ;
int *x = s1, *y = s2 ;
memset ( c, 0, sizeof c ) ;
for ( i = 1 ; i <= n ; i ++ ) c[x[i] = s[i]] ++ ;
for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i - 1] ;
for ( i = n ; i ; i -- ) sa[c[x[i]]--] = i ;

for ( len = 1 ; len < n ; len <<= 1, m = p ) {
p = 0 ;
for ( i = n-len+1 ; i <= n ; i ++ ) y[++p] = i ;
for ( i = 1 ; i <= n ; i ++ )
if (sa[i] > len) y[++p] = sa[i]-len ;

memset ( c, 0, sizeof c ) ;
for ( i = 1 ; i <= n ; i ++ ) c[x[y[i]]] ++ ;
for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i - 1] ;
for ( i = n ; i ; i -- ) sa[c[x[y[i]]]--] = y[i] ;

swap(x, y) ;
x[sa[1]] = p = 1 ;
for ( i = 2 ; i <= n ; i ++ )
if (y[sa[i]] == y[sa[i-1]] && y[sa[i]+len] == y[sa[i-1]+len])
x[sa[i]] = p ;
else x[sa[i]] = ++p ;
if (p >= n) break ;
}

for ( i = 1 ; i <= n ; i ++ ) rnk[sa[i]] = i ;
len = 0 ;
for ( i = 1 ; i <= n ; i ++ ) {
if (len) len-- ;
p = sa[rnk[i]-1] ;
while (s[i+len] == s[p+len]) ++ len ;
height[rnk[i]] = len ;
}
}

bool judge ( int v ) {
int i, ans = 0, rec ;
for ( i = 1 ; i <= n ; i ++ )
if (height[i] < v) rec = 1 ;
else ans = max(ans, ++rec) ;
return ans >= e ;
}
int main() {
int i, l, r, mid, rec ;
for ( i = 1 ; i <= n ; i ++ ) Read(s[i]), b[i] = s[i] ;
sort(b+1, b+n+1) ;
m = unique(b+1, b+n+1)-b-1 ;
for ( i = 1 ; i <= n ; i ++ )
s[i] = lower_bound(b+1, b+m+1, s[i])-b ;
init() ;
l = 1, r = n ;
while (l <= r) {
mid = (l+r)>>1 ;
if (judge(mid)) rec = mid, l = mid+1 ;
else r = mid-1 ;
}
printf ( "%d\n", rec ) ;
return 0 ;
}

# [HAOI2012]高速公路

## Description

Y901高速公路是一条由N1$N-1$段路以及N$N$个收费站组成的东西向的链，我们按照由西向东的顺序将收费站依次编号为1$1$~N$N$，从收费站i$i$行驶到i+1$i+1$或从i+1$i+1$行驶到i$i$需要收取Vi$V_i$的费用。高速路刚建成时所有的路段都是免费的。

N,M105$N, M \le 10^5$

## Solution

E=i=lr12Vi×(il+1)×(ri)(rl+1)2=i=lr12Vi[i2+(l+r1)ilr+r](rl+1)2

i=1ni=n×(n+1)2i=1ni2=n×(n+1)×(2n+1)6

## Code

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
void Read ( LL &x, char c = getchar(), bool f = 0 ) {
for ( x = 0 ; !isdigit(c) ; c = getchar() ) if (c == '-') f = 1 ;
for ( ; isdigit(c) ; c = getchar() ) x = 10*x + c - '0' ;
if (f) x = -x ;
}
LL gcd ( LL a, LL b ) { return b?gcd(b,a%b):a; }
const int maxn = 1e5+5 ;
LL sum1 ( int x ) { return (LL)x*(x+1)/2 ; }
LL sum2 ( int x ) { return (LL)x*(x+1)*(2*x+1)/6 ; }
LL n, m, tree[maxn*3][3], tag[maxn*3] ;
void push_up ( int h ) {
tree[h][0] = tree[h<<1][0]+tree[h<<1|1][0] ;
tree[h][1] = tree[h<<1][1]+tree[h<<1|1][1] ;
tree[h][2] = tree[h<<1][2]+tree[h<<1|1][2] ;
}
void push_down ( int h, int l, int r ) {
int mid = (l+r)>>1 ;
if (tag[h]) {
tag[h<<1] += tag[h] ;
tag[h<<1|1] += tag[h] ;

tree[h<<1][0] += tag[h]*(mid-l+1) ;
tree[h<<1|1][0] += tag[h]*(r-mid) ;

tree[h<<1][1] += tag[h]*(sum1(mid)-sum1(l-1)) ;
tree[h<<1|1][1] += tag[h]*(sum1(r)-sum1(mid)) ;

tree[h<<1][2] += tag[h]*(sum2(mid)-sum2(l-1)) ;
tree[h<<1|1][2] += tag[h]*(sum2(r)-sum2(mid)) ;

tag[h] = 0 ;
}
}
void update ( int h, int l, int r, int x, int y, LL v ) {
if (x <= l && r <= y) {
tag[h] += v ;
tree[h][0] += (r-l+1)*v ;
tree[h][1] += v*(sum1(r)-sum1(l-1)) ;
tree[h][2] += v*(sum2(r)-sum2(l-1)) ;
return ;
}
push_down(h, l, r) ;
int mid = (l+r)>>1 ;
if (y <= mid) update(h<<1, l, mid, x, y, v) ;
else if (x > mid) update(h<<1|1, mid+1, r, x, y, v) ;
else {
update(h<<1, l, mid, x, mid, v) ;
update(h<<1|1, mid+1, r, mid+1, y, v) ;
}
push_up(h) ;
}
LL query ( int h, int l, int r, int x, int y, int v ) {
if (x <= l && r <= y) return tree[h][v] ;
push_down(h, l, r) ;
int mid = (l+r)>>1 ;
if (y <= mid) return query(h<<1, l, mid, x, y, v) ;
else if (x > mid) return query(h<<1|1, mid+1, r, x, y, v) ;
return query(h<<1, l, mid, x, mid, v)+query(h<<1|1, mid+1, r, mid+1, y, v) ;
}
char cmd[5] ;
int main() {
LL l, r, v, rec0, rec1, rec2, rec, d ;
while(m--) {
scanf ( "%s", cmd ) ;
if (cmd[0] == 'C') {
update(1, 1, n, l, r-1, v) ;
} else {
rec0 = query(1, 1, n, l, r-1, 0) ;
rec1 = query(1, 1, n, l, r-1, 1) ;
rec2 = query(1, 1, n, l, r-1, 2) ;

rec = -rec2 + rec1*(r+l-1) + rec0*(r-l*r) ;
v = (r-l+1)*(r-l) ;
v >>= 1 ;
d = gcd(rec, v) ;
rec /= d ;
v /= d ;
printf ( "%lld/%lld\n", rec, v ) ;
}
}
return 0 ;
}

# [SDOI2011]计算器

## Code

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
LL Qpow ( LL a, LL b, LL modd ) {
LL rec = 1 ;
for ( a %= modd; b ; b >>= 1, (a *= a) %= modd )
if (b&1) (rec *= a) %= modd ;
return rec ;
}
LL exgcd ( LL a, LL b, LL &x, LL &y ) {
if (b == 0) {
x = 1, y = 0 ;
return a ;
}
LL d = exgcd(b, a%b, y, x) ;
y -= a/b*x ;
return d ;
}
void solve1() {
LL a, b, c ;
scanf ( "%lld%lld%lld", &a, &b, &c ) ;
printf ( "%lld\n", Qpow(a, b, c) ) ;
}
void solve2() {
LL a, b, c, d, x, y ;
scanf ( "%lld%lld%lld", &a, &c, &b ) ;
d = exgcd(a, b, x, y) ;
if (c%d != 0) {
puts("Orz, I cannot find x!") ;
return ;
}
x = (x+b)%b ;
c /= d ;
x *= c ;
printf ( "%lld\n", x%b ) ;
}
map <LL, LL> g ;
void solve3() {
g.clear() ;
LL a, b, c, rec, i, m ;
scanf ( "%lld%lld%lld", &a, &b, &c ) ;
if (a%c == 0) goto end ;
m = ceil(sqrt(c)) ;
rec = b%c ;
for ( i = 0 ; i <= m ; i ++, (rec *= a) %= c )
if (!g[rec]) g[rec] = i ;
for ( i = 1 ; i <= m ; i ++ ) {
rec = Qpow(a, i*m, c) ;
if (g.count(rec)) {
rec = i*m - g[rec] ;
printf ( "%lld\n", (rec%c+c)%c ) ;
return ;
}
}
end:puts("Orz, I cannot find x!") ;
}
int main() {
int _, type ;
scanf ( "%d%d", &_, &type ) ;
while (_--) {
if (type == 1) solve1() ;
else if (type == 2) solve2() ;
else solve3() ;
}
return 0 ;
}

# [SDOI2013]随机数生成器

## Solution

v$v$次之后到达。发现展开之后是个多项式。

xav1+bi=0v2ai=t

## Code

#include <bits/stdc++.h>
#define LL long long
using namespace std ;
LL modd ;
LL Qpow ( LL a, LL b ) {
LL rec = 1 ;
for ( a %= modd ; b ; b >>= 1, (a *= a) %= modd )
if (b&1) (rec *= a) %= modd ;
return rec ;
}
map <LL, LL> Map ;
LL BSGS ( LL a, LL b ) {
if (b == 1) return 1 ;
LL i, t, m = ceil(sqrt(modd)), rec = b ;
Map.clear() ;
for ( i = 1 ; i <= m ; i ++ ) {
(rec *= a) %= modd ;
if (!Map.count(rec)) Map[rec] = i ;
}
t = Qpow(a, m) ;
rec = 1 ;
for ( i = 1 ; i <= m ; i ++ ) {
(rec *= t) %= modd ;
if (Map.count(rec)) return i*m - Map[rec] + 1 ;
}
return -1 ;
}
int main() {
LL _, a, b, x, t ;
cin >> _ ;
while (_--) {
cin >> modd >> a >> b >> x >> t ;
if (x == t) {
puts("1") ;
continue ;
}
if (a == 0) {
if (b == t) puts("2") ;
else puts("-1") ;
continue ;
}
if (a == 1 && b == 0) {
puts("-1") ;
continue ;
}
if (a == 1) {
cout << ((t-x+modd)%modd)*Qpow(b, modd-2)%modd+1 << endl ;
continue ;
}
t = (a*t%modd - t + modd + b)%modd ;
(t *= Qpow(a*x%modd - x + b + modd, modd-2)) %= modd ;
cout << BSGS(a, t) << endl ;
}
return 0 ;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120