#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>int n, k;intmain(){
std::cin >> n >> k;
std::cout <<(2* n + k -1)/ k +(5* n + k -1)/ k
+(8* n + k -1)/ k << std::endl;return0;}
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}int q;intmain(){int l, r;
q =read();while(q--){
l =read(); r =read();int res = l &1? r - l +1>>1:-(r - l +1>>1);if(!(r - l &1)){if(r &1) res -= r;else res += r;}printf("%d\n", res);}return0;}
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}template<classT>inline T Min(const T &a,const T &b){return a < b ? a : b;}template<classT>inline T Max(const T &a,const T &b){return a > b ? a : b;}typedeflonglong ll;int n, m, X1, Y1, X2, Y2, X3, Y3, X4, Y4;
ll w, b;
ll rects(int xl,int yl,int xr,int yr){if(!(1ll*(xr - xl +1)*(yr - yl +1)&1))return1ll*(xr - xl +1)*(yr - yl +1)>>1;if(xl + yl &1)return1ll*(xr - xl +1)*(yr - yl +1)>>1;return(1ll*(xr - xl +1)*(yr - yl +1)>>1)+1;}
ll stcer(int xl,int yl,int xr,int yr){return1ll*(xr - xl +1)*(yr - yl +1)-rects(xl, yl, xr, yr);}voidwork(){
n =read(); m =read();
X1 =read(); Y1 =read(); X2 =read(); Y2 =read();
X3 =read(); Y3 =read(); X4 =read(); Y4 =read();if(1ll* n * m &1) w =(1ll* n * m >>1)+1, b = w -1;else w = b =1ll* n * m >>1;
w -=rects(X1, Y1, X2, Y2)+rects(X3, Y3, X4, Y4);
b -=stcer(X1, Y1, X2, Y2)+stcer(X3, Y3, X4, Y4);
w +=1ll*(X2 - X1 +1)*(Y2 - Y1 +1);
b +=1ll*(X4 - X3 +1)*(Y4 - Y3 +1);if(Max(X1, X3)<=Min(X2, X4)&&Max(Y1, Y3)<=Min(Y2, Y4)){
w +=rects(Max(X1, X3),Max(Y1, Y3),Min(X2, X4),Min(Y2, Y4));
b +=stcer(Max(X1, X3),Max(Y1, Y3),Min(X2, X4),Min(Y2, Y4));
w -=1ll*(Min(X2, X4)-Max(X1, X3)+1)*(Min(Y2, Y4)-Max(Y1, Y3)+1);}
std::cout << w <<" "<< b << std::endl;}intmain(){int T =read();while(T--)work();return0;}
然后把除第一行、第一列之外的,所有规模为 2x 的 (2n−x−1)2 个正方形全部切成 1×1 的小正方形,这样就得到了答案为 x 时的最多切割次数 q2
如果 q1≤k≤q2 则合法
复杂度 O(tmin(n,31))
代码
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)#define Rof(i, a, b) for (i = a; i >= b; i--)constint N =40;typedeflonglong ll;int n;
ll k, f[N], g[N], p2[N];boolgreaters(ll a, ll b, ll c){if(c <0)return0;if(!b)return a * b <0;return a <(c + b -1)/ b;}voidwork(){int i, j;
ll delta;
std::cin >> n >> k;if(n >31)return(void)printf("YES %d\n", n -1);
Rof (i, n -1,0){if(f[n - i]> k)continue;
ll grids =1ll*(p2[n - i]-1)*(p2[n - i]-1);if(greaters(g[i], grids, k - g[n - i]))continue;return(void)printf("YES %d\n", i);}puts("NO");}intmain(){int i, j, T; std::cin >> T;
f[1]= p2[0]= g[1]=1;
For (i,1,35) p2[i]=2ll* p2[i -1];
For (i,2,35) f[i]=3ll* f[i -1]+1,
g[i]=4ll* g[i -1]+1;while(T--)work();return0;}
E
题意
给定一个 n×m 字符矩阵
求有多少个非空子矩阵
满足能够对于子矩阵的每一行,将该行的字符重新排列
使得子矩阵的每行每列都是回文串
字符集为小写英文字母
1≤n,m≤250
算法: Hash + Manacher
小清新字符串题
先转化下一个子矩阵合法的条件
(1)子矩阵的每一行都能重组成回文串(出现次数为奇数的字符不超过 1 个)
(2)对于子矩阵的任意对称的两行 i 和 j 以及任意字符 c ,都满足子矩阵第 i 行字符 c 的出现次数与第 j 行字符 c 的出现次数相等
条件(1)很容易预处理出
而条件(2)可以对于每一行 i 的每一个区间 [l,r] ,预处理出区间内所有字符的出现次数组成的哈希值 hash[i][l][r]
那么条件(2)就转化成了如果子矩阵跨列 [l,r] ,第 i 行与第 j 行对称,则需要满足 hash[i][l][r]=hash[j][l][r]
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)template<classT>inline T Min(const T &a,const T &b){return a < b ? a : b;}constint N =255, M =26, L = N <<1, ZZQ =998244353, YSY =1e9+7;int n, m, h1[N][N][N], h2[N][N][N], pw1[M], pw2[M], str1[L], str2[L],
ans, R[L], cnt[M];char s[N][N];bool pal[N][N][N];voidmanacher(int n){int i, mx =0, pos;
For (i,1, n){
R[i]= mx > i ?Min(mx - i, R[(pos <<1)- i]):1;while(str1[i - R[i]]== str1[i + R[i]]&& str2[i - R[i]]== str2[i + R[i]]) R[i]++;if(i + R[i]> mx) mx = i + R[i], pos = i;}}voidsolve(int l,int r){int i, tot =0;
str1[0]= str2[0]=-19310918;
For (i,1, n){
str1[++tot]=-19370707;
str2[tot]=-19370707;
str1[++tot]= h1[i][l][r];
str2[tot]= pal[i][l][r]? h2[i][l][r]:-i;}
str1[++tot]=-19370707;
str2[tot]=-19370707;
str1[tot +1]= str2[tot +1]=-19450815;manacher(tot);
For (i,1, tot)if(str2[i]<-1000|| str2[i]>=0)
ans += i &1? R[i]-1>>1: R[i]>>1;}intmain(){int i, j, k;
std::cin >> n >> m;
pw1[0]= pw2[0]=1;
For (i,1,25){
pw1[i]=317ll* pw1[i -1]% ZZQ;
pw2[i]=317ll* pw2[i -1]% YSY;}
For (i,1, n)scanf("%s", s[i]+1);
For (i,1, n) For (j,1, m){int o1 =0, o2 =0, cc =0;
For (k,0,25) cnt[k]=0;
For (k, j, m){int c = s[i][k]-'a';
o1 =(o1 + pw1[c])% ZZQ;
o2 =(o2 + pw2[c])% YSY;if((++cnt[c])&1) cc++;else cc--;
pal[i][j][k]= cc <=1;
h1[i][j][k]= o1; h2[i][j][k]= o2;}}
For (i,1, m) For (j, i, m)solve(i, j);
std::cout << ans << std::endl;return0;}
F
题意
给定 n 个集合
每个集合里有一些区间
有 m 个询问
每次给出 a,b,x,y
询问是否对于每个 i∈[a,b] ,都满足第 i 个集合内存在一个区间包含于 [x,y]
强制在线
1≤n,m≤105 ,1≤k≤3×105 ( k 为总区间个数)
区间端点在 [1,109] 内
算法:主席树
小清新数据结构题
先离散化区间端点
询问可以看成将所有右端点不超过 y 的区间全部加入,设这种情况下第 i 个集合内区间的左端点的最大值 为 lmaxi (第 i 个集合为空则 lmaxi=0 )
那么就是询问 mini=ablmaxi 是否大于等于 x
如果大于等于 x 则输出 yes ,否则 no
建一些线段树,第 i 棵线段树储存所有右端点不超过 i 的区间全部加入时,这种情况下的 lmaxi 及其区间最小值
考虑到空间问题,使用主席树,将区间按右端点排序后,对于所有的 i ,将前 i 个区间建一个历史版本,第 i 个历史版本建在第 i−1 个历史版本上
复杂度 O((n+m+k)logn)
代码
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}template<classT>inline T Max(const T &a,const T &b){return a > b ? a : b;}template<classT>inline T Min(const T &a,const T &b){return a < b ? a : b;}constint N =3e5+5, M = N <<1, L =3e7+5;int n, m, k, tmp, arr[M], rt[N], pos[M], ToT;struct interval
{int l, r, p;} a[N];struct node
{int lc, rc, val;} T[L];inlineboolcomp(interval a, interval b){return a.r < b.r;}voidins(int y,int&x,int l,int r,int p,int val){
T[x =++ToT]= T[y];if(l == r)return(void)(T[x].val =Max(T[x].val, val));int mid = l + r >>1;if(p <= mid)ins(T[y].lc, T[x].lc, l, mid, p, val);elseins(T[y].rc, T[x].rc, mid +1, r, p, val);
T[x].val =Min(T[T[x].lc].val, T[T[x].rc].val);}intquery(int l,int r,int s,int e,int p){if(l == s && r == e)return T[p].val;int mid = l + r >>1;if(e <= mid)returnquery(l, mid, s, e, T[p].lc);elseif(s >= mid +1)returnquery(mid +1, r, s, e, T[p].rc);elsereturnMin(query(l, mid, s, mid, T[p].lc),query(mid +1, r, mid +1, e, T[p].rc));}intmain(){int i, _a, _b, x, y;
n =read(); m =read(); k =read();
For (i,1, k) a[i].l =read(), a[i].r =read(), a[i].p =read();
For (i,1, k) arr[(i <<1)-1]= a[i].l, arr[i <<1]= a[i].r;
std::sort(arr +1, arr +(k <<1)+1);
tmp = std::unique(arr +1, arr +(k <<1)+1)- arr -1;
For (i,1, k){
a[i].l = std::lower_bound(arr +1, arr + tmp +1, a[i].l)- arr;
a[i].r = std::lower_bound(arr +1, arr + tmp +1, a[i].r)- arr;}
std::sort(a +1, a + k +1, comp);
For (i,1, k){ins(rt[i -1], rt[i],1, n, a[i].p, a[i].l);
pos[a[i].r]= i;}
For (i,1, tmp)if(!pos[i]) pos[i]= pos[i -1];while(m--){
_a =read(); _b =read(); x =read(); y =read();
x = std::lower_bound(arr +1, arr + tmp +1, x)- arr;
y = std::upper_bound(arr +1, arr + tmp +1, y)- arr -1;puts(x > y ||query(1, n, _a, _b, rt[pos[y]])< x ?"no":"yes");fflush(stdout);}return0;}