https://www.luogu.org/problem/P3120
首先ON^4的dp很容易想到(数据加强过,所以这个过不了)
code:
#include
using namespace std;
int r,c,k; //行,列,数值限定
int a[751][751];
long long f[751][751]={0};
//f[i][j]:左上f[i][j]严格左上方所有点的路径总数之和
int main()
{
scanf("%d%d%d",&r,&c,&k);
for(int i=0;i
加强的数据完美卡**到N^2*logN**
首先如果没有两点的val值不同这个条件的话,直接维护二维前缀和就好
可是加了这个条件就很烦
还是考虑前缀和,两点的val值不同,那就先考虑两点val值相同的情况,
跟新答案时,用所有的前缀和减掉相同的情况就好
明显就只有权值线段树,
可是不同的val值可能有750*750个
不同的前缀和有750*750个
开不下啊,怎么办?,于是考虑动态开点
就愉(tong)快(ku)的AC了
code:
#include
#define y1 y1_
#define index index_
#define pipe pipe_
#define next next_
#define endl '\n'
#define rgi register int
#define ll long long
#define Pi acos(-1.0)
#define lowbit(x) ((x&(-x)))
#define pb push_back
#define mk make_pair
#define pii pair
#define fst first
#define scd second
using namespace std;
inline int read() {
int f=1,x=0;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=755;
const int MOD=1e9+7;
int n,m,K,a[MAXN][MAXN];
struct SegmentTree{
int ls,rs; ll sum;
}t[MAXN*MAXN*10];
int cnt;
void update(int l,int r,int &rt,int pos,int val) {
if(!rt) rt=++cnt;
if(l==r) {
t[rt].sum=(t[rt].sum+val)%MOD;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(l,mid,t[rt].ls,pos,val);
else update(mid+1,r,t[rt].rs,pos,val);
t[rt].sum=(t[t[rt].ls].sum+t[t[rt].rs].sum)%MOD;
}
ll sum[MAXN],dp[MAXN][MAXN];
ll query(int l,int r,int rt,int pos) {
if(!rt) return 0;
if(r<=pos) return t[rt].sum;
int mid=(l+r)>>1;
if(pos<=mid) return query(l,mid,t[rt].ls,pos);
else return (query(l,mid,t[rt].ls,pos)+query(mid+1,r,t[rt].rs,pos))%MOD;
}
int main() {
// freopen("","r",stdin);
// freopen("","w",stdout);
ios::sync_with_stdio(0);cin.tie(0);/*syn加速*/
n=read(); m=read(); K=read(); cnt=K;
for(rgi i=1;i<=n;++i) for(rgi j=1;j<=m;++j) a[i][j]=read();
for(rgi i=1;i