NC53553. 求和
描述
输入描述
第一行一个整数 。
后面接着 行,每行两个整数,
输出描述
输出一行一个整数表示答案。
示例1
输入:
3 1 1 1 1 1 2
输出:
506
C++14(g++5.4) 解法, 执行用时: 284ms, 内存消耗: 79212K, 提交时间: 2019-12-14 14:02:55
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 998244353; const int N = 2010; int A[N][N], B[N*2][N*2]; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int n; cin >> n; for(int i = 0; i < n; i++) { int a, b; cin >> a >> b; A[a][b]++; } for(int i = 2000; i >= 0; i--) { for(int j = 2000; j >= 0; j--) { A[i][j] = (A[i][j] + A[i+1][j]) % mod; A[i][j] = (A[i][j] + A[i][j+1]) % mod; A[i][j] = (A[i][j] - A[i+1][j+1]) % mod; } } for(int i = 0; i <= 2000; i++) { for(int j = 0; j <= 2000; j++) { B[2000-i][2000-j] = A[i][j]; } } int ans = 0; for(int i = 0; i <= 4000; i++) { for(int j = 0; j <= 4000; j++) { if(!i && !j) continue; if(i) B[i][j] = (B[i][j] + B[i-1][j]) % mod; if(j) B[i][j] = (B[i][j] + B[i][j-1]) % mod; if(i >= 2000 && j >= 2000) { ans = (ans + (ll) B[i][j] * A[i-2000][j-2000]) % mod; } } } ans = (ans - (ll) A[0][0] * A[0][0]) % mod; if(ans < 0) ans += mod; cout << ans << '\n'; return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 566ms, 内存消耗: 168556K, 提交时间: 2019-12-14 12:07:25
#include<bits/stdc++.h> #define ll long long using namespace std; struct aaa{ ll x,y; }a[200010]; ll n,i,j,x,y,ans,f[4010][4010],p=998244353,b[4010][4010]; int main(){ scanf("%lld",&n); for(i=1;i<=n;i++){ scanf("%lld%lld",&a[i].x,&a[i].y); b[a[i].x][a[i].y]++; } for(i=2000;i>=0;i--){ for(j=2000;j>=0;j--){ b[i][j]+=b[i+1][j]+b[i][j+1]-b[i+1][j+1]; //if(b[i][j])printf("%lld %lld %lld\n",i,j,b[i][j]); } } for(i=-2000;i<=2000;i++){ for(j=-2000;j<=2000;j++){ x=i+2000;y=j+2000; if(x>0)f[x][y]+=f[x-1][y]; if(y>0)f[x][y]+=f[x][y-1]; if(i<=0&&j<=0)f[x][y]+=b[-i][-j];f[x][y]%=p; if(i>=0&&j>=0)ans=(ans+f[x][y]*b[i][j])%p; //if(f[x][y]&&b[i][j])printf("%lld %lld %lld %lld\n",i,j,b[i][j],f[x][y]); } } ans=(ans-n*n%p+p)%p; printf("%lld",ans); }