@Chilling
2018-04-27T19:35:05.000000Z
字数 19499
阅读 769
ACM
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1.0)
double dis(double x1, double y1, double x2, double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
double cos_angle(double a, double b, double c)
{
return 0.5 * (a * a + c * c - b * b) / (a * c);
}
double get_area(double x1, double y1, double r1, double x2, double y2, double r2)
{
double d, s, s1_, s2_, s1_tri, s2_tri, an1, an2;
d = dis(x1, y1, x2, y2);
if (d >= r1 + r2 || !r1 || !r2) //相切、相离、考虑等于0
return 0;
if (d + r1 <= r2) //包含
return PI * r1 * r1;
if (d + r2 <= r1) //包含
return PI * r2 * r2;
an1 = acos(cos_angle(r1, r2, d));
an2 = acos(cos_angle(r2, r1, d));
s1_tri = 0.5 * r1 * r1 * sin(an1 * 2);
s2_tri = 0.5 * r2 * r2 * sin(an2 * 2);
s1_ = r1 * r1 * an1;
s2_ = r2 * r2 * an2;
s = (s1_ - s1_tri) + (s2_ - s2_tri);
return s;
}
int area()
{
return abs((a * d + c * f + b * e - a * f - b * c - d * e) / 2);
}
int gcd(int x, int y)
{
if (y == 0)return x;
else
return gcd(y, x % y);
}
int main ()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &e, &f);
int s = area();
int l1 = gcd(abs(a - c), abs(b - d));
int l2 = gcd(abs(a - e), abs(b - f));
int l3 = gcd(abs(c - e), abs(d - f));
printf("%d\n", s - (l1 + l2 + l3) / 2 + 1);
}
return 0;
}
矩形:
正方形:
给出锥形的表面积(包括底部)S,当的时候,体积最大。
priority_queue<int, vector<int>, greater<int> >a;
(小者优先)
struct cmp1
{
bool operator ()(int x, int y)
{
return x > y;//小的优先级高
}
};
struct node
{
int x, y;
friend bool operator < (node a, node b)
{
return a.x > b.x;//结构体中,x小的优先级高
}
};
priority_queue<int, vector<int>, cmp1>q2;
priority_queue<node>q4;
//几种不同类型有固定数量的物品拆分成01背包
//这个姿势貌似更好
for (i = 1; i <= m; i++)
{
scanf("%d%d%d", &p, &h, &c); //价值,重量,个数
for (j = 1; j <= c; j *= 2)
{
v[cnt] = j * p; //分堆后每堆的价值
w[cnt++] = j * h; //每堆的重量
c -= j;
}
if (c > 0)
{
v[cnt] = c * p;
w[cnt++] = c * h;
}
}
第一类斯特林数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目。
递推公式为: 。
边界条件:
一些性质:
第二类斯特林数是把包含n个元素的集合划分为正好k个非空子集的方法的数目。
递推公式为: ,
考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的
不可辨别的集合,方法数为S(p-1,k-1);
也可以前p-1种物品构成k个非空的不可辨别的集合,
第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。
n场比赛,m张牌(n>=m)每场比赛用一张牌,
每张牌至少用一次,问有几种方案数。
分析:n场比赛划分成m个集合,每个集合里的比赛只用同一张牌,
没有空的集合。也就是说把包含n个元素的集合划分为正好m个非空子集的方法的数目,
再乘m的全排列。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
ll sum[110][110];
ll jiec[102];
int main()
{
jiec[0] = 1;
jiec[1] = 1;
jiec[2] = 2;
for (ll i = 3; i < 102; i++)
jiec[i] = (jiec[i - 1] * i) % mod;
for (ll i = 0; i <= 102; i++)
{
for (ll j = 0; j <= 102; j++)
{
if ( j == 0 || j > i )sum[i][j] = 0;
else if ( i == j || j == 1 )sum[i][j] = 1;
else sum[i][j] = ( sum[i - 1][j - 1] + j * sum[i - 1][j] ) % mod;
}
}
int n, m;
while ( scanf("%d %d", &n, &m) != EOF )
{
printf("%lld\n", (jiec[m]*sum[n][m] ) % mod );
}
return 0;
}
现在给你一个数集S的大小n,请输出将它划分为集合的方法总数ans是多少?
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 5002;
ll sum[2][maxn];
ll ans[maxn];
void cal()
{
for (ll i = 0; i < maxn; i++)
{
ans[i] = 0;
for (ll j = 0; j < maxn; j++)
{
if ( j == 0 || j > i )sum[i % 2][j] = 0;
else if ( i == j || j == 1 )sum[i % 2][j] = 1;
else sum[i % 2][j] = ( sum[ (i - 1) % 2 ][j - 1] + j * sum[ (i - 1) % 2 ][j] ) % mod;
ans[i] = (ans[i] + sum[i % 2][j]) % mod;
}
}
}
int main()
{
cal();
int n, cas = 1;
while ( scanf("%d", &n) != EOF )
{
printf("Case #%d: %lld\n", cas++, ans[n] % mod );
}
return 0;
}
LL quick(LL x,LL m,LL n)//x^m%mod
{
LL ans=1;
while(m>0)
{
if(m%2==1)
ans=ans*x%mod;
x=x*x%mod;
m=m/2;
}
return ans;
}
struct Matrix
{
int m[10][10];
}M;
Matrix Mult(Matrix a,Matrix b) //矩阵乘法
{
Matrix ans;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
ans.m[i][j]=0;
for(int k=0;k<n;k++)
{
ans.m[i][j]+=a.m[i][k]*b.m[k][j];
ans.m[i][j]%=mod;
}
}
}
return ans;
}
Matrix quickpow(Matrix a,int b) //矩阵a的b次方-快速幂
{
Matrix ans;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
ans.m[i][j]=1;
else
ans.m[i][j]=0;
}
}
while(b)
{
if(b&1)
ans=Mult(ans,a);
a=Mult(a,a);
b/=2;
}
return ans;
}
int phi(int n)
{
int m = (int)sqrt(n + 0.5);
int ans = n;
for (int i = 2; i <= m; i++)
if (n % i == 0)
{
ans = ans / i * (i - 1);
while (n % i == 0)
n /= i;
}
if (n > 1)
ans = ans / n * (n - 1);
return ans;
}
bool isprime[N];
void primeform(int maxn) //0到maxn内的素数
{
memset(isprime, true, sizeof(isprime));
int m = (int)sqrt(maxn + 0.5) + 1;
for (int i = 2; i < m; i++)
{
if (isprime[i])
for (int j = i * 2; j <= maxn; j += i)
isprime[j] = false;
}
}
bool isprime[maxn]; //是否素数
int prime[maxn]; //素数表
void primeform(int maxn) //0-maxn素数
{
int cnt = 0;
memset(isprime, true, sizeof(isprime));
for (int i = 2; i <= maxn; i++)
{
if (isprime[i])
prime[cnt++] = i; //打表
for (int j = 0; (j < cnt && i * prime[j] <= maxn); j++)
{
isprime[i * prime[j]] = false;
if (i % prime[j] == 0)
break;
}
}
}
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL f[340000], g[340000], n;
void init()
{
LL i, j, m;
for (m = 1; m * m <= n; ++m)
f[m] = n / m - 1;
for (i = 1; i <= m; ++i)
g[i] = i - 1;
for (i = 2; i <= m; ++i)
{
if (g[i] == g[i - 1])
continue;
for (j = 1; j <= min(m - 1, n / i / i); ++j)
{
if (i * j < m)
f[j] -= f[i * j] - g[i - 1];
else
f[j] -= g[n / i / j] - g[i - 1];
}
for (j = m; j >= i * i; --j)
g[j] -= g[j / i] - g[i - 1];
}
}
int main()
{
while (scanf("%lld", &n) != EOF)
{
init();
printf("%lld\n", f[1]);
}
return 0;
}
//求阶乘最后非零位,复杂度O(nlogn)
//返回该位,n以字符串方式传入
#define MAXN 10000
int lastdigit(char* buf)
{
const int mod[20] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8, 4, 4, 8, 4, 6, 8, 8, 6, 8, 2};
int len = strlen(buf), a[MAXN], i, c, ret = 1;
if (len == 1)
return mod[buf[0] - '0'];
for (i = 0; i < len; i++)
a[i] = buf[len - 1 - i] - '0';
for (; len; len -= !a[len - 1])
{
ret = ret * mod[a[1] % 2 * 10 + a[0]] % 5;
for (c = 0, i = len - 1; i >= 0; i--)
c = c * 10 + a[i], a[i] = c / 5, c %= 5;
}
return ret + ret % 2 * 5;
}
int ans = double(n - log10(n) - log10(log(10)));
printf("%d\n", ans + 1);
求 mod 的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
通过求b关于p的乘法逆元k,将a乘上k再模p,即 mod 。其结果与 mod 等价
//ax+by=gcd(a,b),所求的x即为a mod b的逆元(a^(-1)),y为b mod a的逆元
void ex_gcd(LL a,LL b)
{
if(b==0)
{
x=1;
y=0;
return ;
}
ex_gcd(b,a%b);
int t=x;
x=y;
y=t-a/b*y;
}
不能表示的数的个数:(A-1)*(B-1)/2
最大不能表示的数:A*B-A-B
对于C(n,k),若n&k == k ,则c(n,k)为奇数,否则为偶数
另类递推式:
递推关系的解为:
递推关系的另类解为:
a[0]=1,a[1]=1;
for(i=2;i<=n;i++)
a[i]=a[i-1]*(4*i-2)/(i+1);
a[0]=1,a[1]=1;
for(i=2;i<=n;i++)
for(j=0;j<i;j++)
a[i]=a[i]+a[j]*a[i-j-1];
递推式:
int lowbit(int x)
{
return x & (-x);
}
void change(int x, int y) //在x点加上值y
{
for (int i = x; i <= n; i += lowbit(i))
a[i] += y;
}
int sum(int x) //1到x的和
{
int sum = 0;
for (int i = x; i > 0; i -= lowbit(i))
sum += a[i];
return sum;
}
#include<stdio.h>
#include<string.h>
#define N 3000
int f[N];
int main()
{
int i, j, n;
scanf("%d", &n);
memset(f, 0, sizeof(f));
f[0] = 1;
for (i = 2; i <= n; i++)
{
int c = 0;
for (j = 0; j < N; j++)
{
int s = f[j] * i + c;
f[j] = s % 10;
c = s / 10;
}
}
for (j = N - 1; j >= 0; j--)
{
if (f[j])
break;
}
for (i = j; i >= 0; i--)
{
printf("%d", f[i]);
}
printf("\n");
return 0;
}
#include<stdio.h>
#include<string.h>
char sa[1111], sb[1111];
int s[1111], la, lb, i, flag, k, j;
void jianfa()
{
for (i = lb - 1; i > 0; i--)
{
if (sa[i] < sb[i])
{
sa[i] += 10;
sa[i - 1]--;
}
}
for (i = lb - 1; i >= 0; i--)
sa[i] = sa[i] - sb[i] + '0';
}
int main()
{
while (scanf("%s%s", sa, sb) != EOF)
{
memset(s, 0, sizeof(s));
k = 0;
flag = 1;
la = strlen(sa);
lb = strlen(sb);
if (la < lb || (la == lb && strcmp(sa, sb) < 0))
printf("0\n");
else
{
while (flag)
{
while (strcmp(sa, sb) >= 0)
{
jianfa();
s[k]++;
}
k++;
if (la == lb)
flag = 0;
for (i = lb; i >= 1; i--)
sb[i] = sb[i - 1];
sb[0] = '0';
lb++;
sb[lb] = '\0';
}
}
for (i = 0; i < k; i++)
if (s[i] != 0)
break;
for (j = i; j < k; j++)
printf("%d", s[j]);
printf("\n");
}
return 0;
}
#include<stdio.h>
#include<string.h>
int a[555], b[555], s[555], la, lb, i, l;
void jiafa()
{
memset(s, 0, sizeof(s));
for (i = 0; i < l; i++)
s[i] = a[i] + b[i];
for (i = 0; i <= l; i++)
{
s[i + 1] += s[i] / 10;
s[i] %= 10;
}
for (i = l; i > 0; i--)
if (s[i] == 0)
l--;
else break;
for (i = l; i >= 0; i--)
printf("%d", s[i]);
printf("\n");
}
int main()
{
char sa[555], sb[555];
while (scanf("%s%s", sa, sb) != EOF)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
la = strlen(sa);
lb = strlen(sb);
for (i = 0; i < la; i++)
a[la - i - 1] = sa[i] - '0';
for (i = 0; i < lb; i++)
b[lb - i - 1] = sb[i] - '0';
l = la > lb ? la : lb;
jiafa();
}
return 0;
}
#include<stdio.h>
#include<string.h>
void jianfa(int *a, int *b, int l)
{
int i, j, s[111], flag = 0;
memset(s, 0, sizeof(s));
for (i = 0; i < l - 1; i++)
{
if (a[i] < b[i])
{
a[i] += 10;
a[i + 1]--;
}
s[i] = a[i] - b[i];
}
s[l - 1] = a[l - 1] - b[l - 1];
for (i = l - 1; i >= 0; i--)
{
if (s[i] != 0)
{
flag = 1;
break;
}
}
if (flag == 0)
printf("0\n");
else
for (j = i; j >= 0; j--)
printf("%d", s[j]);
printf("\n");
}
int f(int *a, int *b, int la, int lb)
{
int i;
for (i = la - 1; i >= 0; i--)
{
if (a[i] > b[i])
{
return 1;
break;
}
if (a[i] < b[i])
{
return 0;
break;
}
}
return -1;
}
int main()
{
char sa[111], sb[111];
int a[111], b[111], ta, tb, i, j, flag, la, lb;
while (scanf("%s%s", sa, sb) != EOF)
{
ta = 0, tb = 0;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
la = strlen(sa);
lb = strlen(sb);
for (i = 0, j = la - 1; j >= 0; i++, j--)
a[i] = sa[j] - '0';
for (i = 0, j = lb - 1; j >= 0; i++, j--)
b[i] = sb[j] - '0';
for (i = la - 1; i >= 0; i--)
{
if (a[i] != 0)
{
ta = 1;
la = i + 1;
break;
}
}
for (i = lb - 1; i >= 0; i--)
{
if (b[i] != 0)
{
tb = 1;
lb = i + 1;
break;
}
}
if (ta + tb == 0)
printf("0\n");
else
{
if (la < lb)
{
printf("-");
jianfa(b, a, lb);
}
else if (la > lb)
jianfa(a, b, la);
else
{
if (f(a, b, la, lb) == 1)
jianfa(a, b, la);
else if (f(a, b, la, lb) == 0)
{
printf("-");
jianfa(b, a, lb);
}
else
printf("0\n");
}
}
}
return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
char sa[44], sb[44];
int a[44], b[44], la, lb, i, j, sum[88], k, x;
while (scanf("%s%s", sa, sb) != EOF)
{
k = 0;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(sum, 0, sizeof(sum));
la = strlen(sa);
lb = strlen(sb);
for (i = 0, j = la - 1; j >= 0; j--, i++)
a[i] = sa[j] - '0';
for (i = 0, j = lb - 1; j >= 0; j--, i++)
b[i] = sb[j] - '0';
for (i = 0; i < la; i++)
{
for (j = 0, k = i; j < lb; j++)
{
sum[k] += a[i] * b[j];
k++;
}
}
for (i = 0; i < k - 1; i++)
{
sum[i + 1] += sum[i] / 10;
sum[i] %= 10;
}
if (sum[k - 1] >= 10)
{
sum[k] = sum[k - 1] / 10;
sum[k - 1] %= 10;
x = k;
}
else
x = k - 1;
for (i = x; i >= 0; i--)
printf("%d", sum[i]);
printf("\n");
}
}
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[50005], dpmin[50005][16], dpmax[50005][16];
int main()
{
int i, n, q, st, en, j, d;
while (scanf("%d%d", &n, &q) != EOF)
{
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (i = 1; i <= n; i++)
{
dpmin[i][0] = a[i];
dpmax[i][0] = a[i];
}
for (i = 1; (1 << i) <= n; i++) //区间长度
for (j = 1; j + (1 << i) - 1 <= n; j++) //起点
{
dpmax[j][i] = max(dpmax[j][i - 1], dpmax[j + (1 << i - 1)][i - 1]);
dpmin[j][i] = min(dpmin[j][i - 1], dpmin[j + (1 << i - 1)][i - 1]);
}
while (q--)
{
scanf("%d%d", &st, &en);
d = 0;
while ((1 << d + 1) <= en - st + 1) d++;
printf("%d\n", (max(dpmax[st][d], dpmax[en - (1 << d) + 1][d]) - min(dpmin[st][d], dpmin[en - (1 << d) + 1][d])));
}
}
return 0;
}
#include<stdio.h>
#include<algorithm>
using namespace std;
int mp[255][255];
int dpmin[255][255][8][8]; //若起点为(0,0),2^8=256
int dpmax[255][255][8][8];
//二维RMQ,dp[x][y][i][j]
//表示从(x,y)点到右下角为(x+2^i-1,y+2^j-1)矩形内最小值
void RMQ(int n, int m) //n*m的矩阵
{
for (int i = 0; (1 << i) <= n; i++)
{
for (int j = 0; (1 << j) <= m; j++)
{
if (!i && !j) continue;
for (int r = 1; r + (1 << i) - 1 <= n; r++)
for (int c = 1; c + (1 << j) - 1 <= m; c++)
{
if (!j)
{
dpmax[r][c][i][j] = max(dpmax[r][c][i - 1][j], dpmax[r + (1 << (i - 1))][c][i - 1][j]);
dpmin[r][c][i][j] = min(dpmin[r][c][i - 1][j], dpmin[r + (1 << (i - 1))][c][i - 1][j]);
}
else
{
dpmax[r][c][i][j] = max(dpmax[r][c][i][j - 1], dpmax[r][c + (1 << (j - 1))][i][j - 1]);
dpmin[r][c][i][j] = min(dpmin[r][c][i][j - 1], dpmin[r][c + (1 << (j - 1))][i][j - 1]);
}
}
}
}
}
int querymax(int lx, int ly, int rx, int ry)
{
int kx = 0, ky = 0;
while (lx + (1 << (1 + kx)) - 1 <= rx) kx++;
while (ly + (1 << (1 + ky)) - 1 <= ry) ky++;
int m1 = dpmax[lx][ly][kx][ky];
int m2 = dpmax[rx - (1 << kx) + 1][ly][kx][ky];
int m3 = dpmax[lx][ry - (1 << ky) + 1][kx][ky];
int m4 = dpmax[rx - (1 << kx) + 1][ry - (1 << ky) + 1][kx][ky];
return max(max(m1, m2), max(m3, m4));
}
int querymin(int lx, int ly, int rx, int ry)
{
int kx = 0, ky = 0;
while (lx + (1 << (1 + kx)) - 1 <= rx) kx++;
while (ly + (1 << (1 + ky)) - 1 <= ry) ky++;
int m1 = dpmin[lx][ly][kx][ky];
int m2 = dpmin[rx - (1 << kx) + 1][ly][kx][ky];
int m3 = dpmin[lx][ry - (1 << ky) + 1][kx][ky];
int m4 = dpmin[rx - (1 << kx) + 1][ry - (1 << ky) + 1][kx][ky];
return min(min(m1, m2), min(m3, m4));
}
int main()
{
int n, b, q;
scanf("%d%d%d", &n, &b, &q);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
scanf("%d", &mp[i][j]);
dpmax[i][j][0][0] = mp[i][j];
dpmin[i][j][0][0] = mp[i][j];
}
RMQ(n, n);
while (q--)
{
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", querymax(x, y, x + b - 1, y + b - 1) - querymin(x, y, x + b - 1, y + b - 1));
}
return 0;
}
#include <bits/stdc++.h>
#define MAXN 100010
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
int l, r; //区间[l,r]
int add;//区间的延时标记
int sum;//区间和
int mx; //区间最大值
int mn; //区间最小值
} tree[MAXN << 2]; //一定要开到4倍多的空间
void pushup(int index)
{
tree[index].sum = tree[index << 1].sum + tree[index << 1 | 1].sum;
tree[index].mx = max(tree[index << 1].mx, tree[index << 1 | 1].mx);
tree[index].mn = min(tree[index << 1].mn, tree[index << 1 | 1].mn);
}
void pushdown(int index)
{
//说明该区间之前更新过
//要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新
if (tree[index].add > 0)
{
//替换原来的值
/*
tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
tree[index<<1].mx = tree[index].add;
tree[index<<1|1].mx = tree[index].add;
tree[index<<1].mn = tree[index].add;
tree[index<<1|1].mn = tree[index].add;
tree[index<<1].add = tree[index].add;
tree[index<<1|1].add = tree[index].add;
tree[index].add = 0;*/
//在原来的值的基础上加上val
tree[index << 1].sum += (tree[index << 1].r - tree[index << 1].l + 1) * tree[index].add;
tree[index << 1 | 1].sum += (tree[index << 1 | 1].r - tree[index << 1 | 1].l + 1) * tree[index].add;
tree[index << 1].mx += tree[index].add;
tree[index << 1 | 1].mx += tree[index].add;
tree[index << 1].mn += tree[index].add;
tree[index << 1 | 1].mn += tree[index].add;
tree[index << 1].add += tree[index].add;
tree[index << 1 | 1].add += tree[index].add;
tree[index].add = 0;
}
}
void build(int l, int r, int index)
{
tree[index].l = l;
tree[index].r = r;
tree[index].add = 0;//刚开始一定要清0
if (l == r)
{
scanf("%d", &tree[index].sum);
tree[index].mn = tree[index].mx = tree[index].sum;
return ;
}
int mid = (l + r) >> 1;
build(l, mid, index << 1);
build(mid + 1, r, index << 1 | 1);
pushup(index);
}
void updata(int l, int r, int index, int val)
{
if (l <= tree[index].l && r >= tree[index].r)
{
/*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
个数,所以区间和 以及 最值为:
*/
/*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
tree[index].mn = val;
tree[index].mx = val;
tree[index].add = val;//延时标记*/
//在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
//个数,所以区间和 以及 最值为:
tree[index].sum += (tree[index].r - tree[index].l + 1) * val;
tree[index].mn += val;
tree[index].mx += val;
tree[index].add += val;//延时标记
return ;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r) >> 1;
if (l <= mid)
{
updata(l, r, index << 1, val);
}
if (r > mid)
{
updata(l, r, index << 1 | 1, val);
}
pushup(index);
}
int query(int l, int r, int index)
{
if (l <= tree[index].l && r >= tree[index].r)
{
//return tree[index].sum;
return tree[index].mx;
//return tree[index].mn;
}
pushdown(index);
int mid = (tree[index].l + tree[index].r) >> 1;
int ans = 0;
int Max = 0;
int Min = inf;
if (l <= mid)
{
ans += query(l, r, index << 1);
Max = max(query(l, r, index << 1), Max);
Min = min(query(l, r, index << 1), Min);
}
if (r > mid)
{
ans += query(l, r, index << 1 | 1);
Max = max(query(l, r, index << 1 | 1), Max);
Min = min(query(l, r, index << 1 | 1), Min);
}
//return ans;
return Max;
//return Min;
}
int main()
{
int n, m, q, x, y, z;
while (~scanf("%d%d", &n, &m))
{
build(1, n, 1);
while (m--)
{
scanf("%d", &q);
if (q == 1)
{
cout << "查询:(x,y)" << endl;
scanf("%d %d", &x, &y);
cout << query(x, y, 1) << endl;
}
else
{
cout << "更新(x,y)为z:" << endl;
scanf("%d %d %d", &x, &y, &z);
updata(x, y, 1, z);
for (int i = 1; i <= n; ++i)
{
printf("a[%d] = %d\n", i, query(i, i, 1));
}
}
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;
struct Nodey
{
int l, r;
int Max, Min;
};
int locy[MAXN], locx[MAXN];
struct Nodex
{
int l, r;
Nodey sty[MAXN * 4];
void build(int i, int _l, int _r)
{
sty[i].l = _l;
sty[i].r = _r;
sty[i].Max = -INF;
sty[i].Min = INF;
if (_l == _r)
{
locy[_l] = i;
return;
}
int mid = (_l + _r) / 2;
build(i << 1, _l, mid);
build((i << 1) | 1, mid + 1, _r);
}
int queryMin(int i, int _l, int _r)
{
if (sty[i].l == _l && sty[i].r == _r)
return sty[i].Min;
int mid = (sty[i].l + sty[i].r) / 2;
if (_r <= mid)return queryMin(i << 1, _l, _r);
else if (_l > mid)return queryMin((i << 1) | 1, _l, _r);
else return min(queryMin(i << 1, _l, mid), queryMin((i << 1) | 1, mid + 1, _r));
}
int queryMax(int i, int _l, int _r)
{
if (sty[i].l == _l && sty[i].r == _r)
return sty[i].Max;
int mid = (sty[i].l + sty[i].r) / 2;
if (_r <= mid)return queryMax(i << 1, _l, _r);
else if (_l > mid)return queryMax((i << 1) | 1, _l, _r);
else return max(queryMax(i << 1, _l, mid), queryMax((i << 1) | 1, mid + 1, _r));
}
} stx[MAXN * 4];
int n;
void build(int i, int l, int r)
{
stx[i].l = l;
stx[i].r = r;
stx[i].build(1, 1, n);
if (l == r)
{
locx[l] = i;
return;
}
int mid = (l + r) / 2;
build(i << 1, l, mid);
build((i << 1) | 1, mid + 1, r);
}
//修改值
void Modify(int x, int y, int val)
{
int tx = locx[x];
int ty = locy[y];
stx[tx].sty[ty].Min = stx[tx].sty[ty].Max = val;
for (int i = tx; i; i >>= 1)
for (int j = ty; j; j >>= 1)
{
if (i == tx && j == ty)continue;
if (j == ty)
{
stx[i].sty[j].Min = min(stx[i << 1].sty[j].Min, stx[(i << 1) | 1].sty[j].Min);
stx[i].sty[j].Max = max(stx[i << 1].sty[j].Max, stx[(i << 1) | 1].sty[j].Max);
}
else
{
stx[i].sty[j].Min = min(stx[i].sty[j << 1].Min, stx[i].sty[(j << 1) | 1].Min);
stx[i].sty[j].Max = max(stx[i].sty[j << 1].Max, stx[i].sty[(j << 1) | 1].Max);
}
}
}
int queryMin(int i, int x1, int x2, int y1, int y2)
{
if (stx[i].l == x1 && stx[i].r == x2)
return stx[i].queryMin(1, y1, y2);
int mid = (stx[i].l + stx[i].r) / 2;
if (x2 <= mid)return queryMin(i << 1, x1, x2, y1, y2);
else if (x1 > mid)return queryMin((i << 1) | 1, x1, x2, y1, y2);
else return min(queryMin(i << 1, x1, mid, y1, y2), queryMin((i << 1) | 1, mid + 1, x2, y1, y2));
}
int queryMax(int i, int x1, int x2, int y1, int y2)
{
if (stx[i].l == x1 && stx[i].r == x2)
return stx[i].queryMax(1, y1, y2);
int mid = (stx[i].l + stx[i].r) / 2;
if (x2 <= mid)return queryMax(i << 1, x1, x2, y1, y2);
else if (x1 > mid)return queryMax((i << 1) | 1, x1, x2, y1, y2);
else return max(queryMax(i << 1, x1, mid, y1, y2), queryMax((i << 1) | 1, mid + 1, x2, y1, y2));
}
int main()
{
int T;
scanf("%d", &T);
int iCase = 0;
while (T--)
{
iCase++;
printf("Case #%d:\n", iCase);
scanf("%d", &n);
build(1, 1, n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
int a;
scanf("%d", &a);
Modify(i, j, a);
}
int q;
int x, y, L;
scanf("%d", &q);
while (q--)
{
scanf("%d%d%d", &x, &y, &L);
int x1 = max(x - L / 2, 1);
int x2 = min(x + L / 2, n);
int y1 = max(y - L / 2, 1);
int y2 = min(y + L / 2, n);
int Max = queryMax(1, x1, x2, y1, y2); //左下角右上角
int Min = queryMin(1, x1, x2, y1, y2);
int t = (Max + Min) / 2;
printf("%d\n", t);
Modify(x, y, t);
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
char s1[maxn],s2[maxn];
int Next[maxn];//最长前后缀
/**串s中t出现的次数,s叫做主串,t叫做模式串**/
void getNext(char s[])
{
int len = strlen(s);
Next[0] = -1;
int j = 0, k = -1;
while(j < len)
{
if(k == -1 || s[j] == s[k])
Next[++j] = ++k;
else
k = Next[k];
}
}
/**
返回模式串t在主串s中首次出现的位置,返回的位置是从0开始的。
**/
int KMP_Index(char s[],char t[])
{
int i = 0, j = 0;
int tlen = strlen(t);
int slen = strlen(s);
getNext(t);
while(i < slen && j < tlen)
{
if(j == -1 || s[i] == t[j])
{
i++; j++;
}
else
j = Next[j];
}
if(j == tlen)
return i - tlen;
else
return -1;
}
/**
返回模式串t在主串s中出现的次数
**/
int KMP_Count(char s[], char t[])///可重叠
{
getNext(t);
int cnt = 0;
int i = 0, j = 0;
int slen = strlen(s);
int tlen = strlen(t);
while(i < slen)
{
if(j == -1 || s[i] == t[j])
{
++i;
++j;
}
else j = Next[j];
if(j == tlen)
{
++cnt;
//j = 0; //要求不可重叠
}
}
return cnt;
}
void KMP_Count2(char t[])///统计单串中从某个位置以前有多少重复的串
{
int tlen=strlen(t);
for(int i=2;i<=tlen;++i)
{
int tmp=i-Next[i];
if(i%tmp==0&&i/tmp>1)
printf("\t位置:%d 个数:%d\n",i,i/tmp);
}
}
int main()
{
while(scanf("%s%s",s1,s2)!=EOF)
{
printf("%d %d\n",KMP_Index(s1,s2),KMP_Count(s1,s2));
}
return 0;
}
int n, m, k;
Complex x1[maxn], x2[maxn];
bool p[maxn], q[maxn];
void multiply(bool *p, int &n, bool *q, int m){
int len = 1;
while(len <= n + m) len <<= 1;
for(int i = 0; i < len; i++) x1[i] = Complex(i <= n ? p[i] : 0, 0);
for(int i = 0; i < len; i++) x2[i] = Complex(i <= m ? q[i] : 0, 0);
fft(x1, len, 1);
fft(x2, len, 1);
for(int i = 0; i < len; i++) x1[i] = x1[i] * x2[i];
fft(x1, len, -1);
for(int i = 0; i <= n + m; i++) p[i] = x1[i].real() > 0.5;
n += m;
}
int main()
{
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++){
int x;
scanf("%d", &x);
q[x] = 1;
}
m = 1000;
n = 0;
p[0] = 1;
while(k)
{
if(k & 1) multiply(p, n, q, m);
if(k > 1) multiply(q, m, q, m);
k >>= 1;
}
for(int i = 1; i <= n; i++) if(p[i]) printf("%d ", i); printf("\n");
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int f[maxn], S[maxn];
int sg[maxn];
void getsg(int n, int m)
{
memset(sg, 0, sizeof(sg));
for (int j, i = 1; i <= n; i++)
{
memset(S, 0, sizeof(S));
for (j = 0; j <= m; j++)
{
if (i - f[j] >= 0)
S[sg[i - f[j]]] = 1;
}
for (j = 0; j <= n; j++)
if (!S[j])break;
sg[i] = j;
}
}
#include<bits/stdc++.h>
using namespace std;
#define ld double
const int SZ = 1e5;
int n;
typedef vector<ld> vld;
vld ps[2333];
int pn = 0, fail[SZ];
ld x[SZ], delta[SZ];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%lf", x + i);
for (int i = 1; i <= n; i++)
{
ld dt = -x[i];
for (int j = 0; j < ps[pn].size(); j++)
dt += x[i - j - 1] * ps[pn][j];
delta[i] = dt;
if (fabs(dt) <= 1e-7) continue;
fail[pn] = i;
if (!pn)
{
ps[++pn].resize(1);
continue;
}
vld&ls = ps[pn - 1];
ld k = -dt / delta[fail[pn - 1]];
vld cur;
cur.resize(i - fail[pn - 1] - 1); //trailing 0
cur.push_back(-k);
for (int j = 0; j < ls.size(); j++) cur.push_back(ls[j]*k);
if (cur.size() < ps[pn].size()) cur.resize(ps[pn].size());
for (int j = 0; j < ps[pn].size(); j++) cur[j] += ps[pn][j];
ps[++pn] = cur;
}
for (unsigned g = 0; g < ps[pn].size(); g++)
printf("%f ", ps[pn][g]);
return 0;
}