#include<cstdio>#include<algorithm>#include<cstring>usingnamespace std;constint maxn =10000010;int a[maxn], b[maxn], N;typedeflonglong ll;int ans;intmain(){scanf("%d",&N);for(int i =0; i < N; i++){int x;scanf("%d",&x);++a[x];}for(int i =2; i <=10000000; i++){if(!a[i])continue;
b[i]+= a[i];for(int j =2;(ll)i * j <=10000000; j++){
b[i * j]=max(b[i * j], b[i]);}
ans =max(ans, b[i]);}printf("%d\n", ans + a[1]);return0;}
J.Matrix Subtraction
二维树状数组可以写。这里就是用树状数组写的。
二位差分也可以写。在循环的时候求前缀和就行。
#include<cstdio>#include<cstring>#include<algorithm>usingnamespace std;constint maxn =1010;typedeflonglong ll;int N, M, A, B;
ll tr[maxn][maxn];intlowbit(int x){return x &-x;}voidadd(int x,int y, ll val){for(int i = x; i <= N; i +=lowbit(i)){for(int j = y; j <= M; j +=lowbit(j)){
tr[i][j]+= val;}}}
ll query(int x,int y){
ll res =0;for(int i = x; i; i -=lowbit(i)){for(int j = y; j; j -=lowbit(j)){
res += tr[i][j];}}return res;}voidinsert(int x1,int y1,int x2,int y2, ll val){add(x1, y1, val);add(x1, y2 +1,-val);add(x2 +1, y1,-val);add(x2 +1, y2 +1, val);}//void Print() {// for (int i = 1; i <= N; i++) {// for (int j = 1; j <= M; j++) {// printf("%lld ", query(i, j));// }// printf("\n");// }//}intmain(){int T;scanf("%d",&T);while(T--){memset(tr,0,sizeof tr);scanf("%d%d%d%d",&N,&M,&A,&B);for(int i =1; i <= N; i++){for(int j =1; j <= M; j++){
ll x;scanf("%lld",&x);insert(i, j, i, j, x);}}bool flag =true;for(int i =1; i <= N; i++){for(int j =1; j <= M; j++){
ll tmp =query(i, j);if(tmp <0){
flag =false;break;}if(i + A -1> N || j + B -1> M)continue;insert(i, j, i + A -1, j + B -1,-tmp);//Print();}if(!flag)break;}for(int i =1; i <= N; i++){if(!flag)break;for(int j =1; j <= M; j++){
ll tmp =query(i, j);if(tmp) flag =false;}}if(flag)printf("^_^\n");elseprintf("QAQ\n");}return0;}