2020 CCPC-Wannafly Winter Camp Day6
A. Convolution
题意:
给出序列\(a_{1...n}\),求\(\displaystyle \sum_{i=1}^n\sum_{j=1}^n2^{a_ia_j}\)。
\(n\leq 10^5,a_i\leq 10^5\)。
思路:
有了这个之后,我们构造多项式\(\displaystyle f(x)=\sum_{i=0}^{n}(\sqrt{2})^{-a_i^2}x^{a_i}\)。
对于第二个求和式,直接卷积计算即可。
\(2\)的二次剩余可直接暴力得到。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/18 21:10:44
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 4e5 + 5, P = 998244353, G = 3, Gi = 332748118;
const int p = 116195171;
int n, m, r[N];
ll a[N], b[N];//注意空间要开四倍
ll qpow(ll a, ll k) {
ll ans = 1;
while(k) {
if(k & 1) ans = (ans * a ) % P;
a = (a * a) % P;
k >>= 1;
}
return ans;
}
void NTT(ll *A, int type, int n) {
for(int i = 0; i < n; i++)
if(i < r[i]) swap(A[i], A[r[i]]);
for(int mid = 1; mid < n; mid <<= 1) {
ll Wn = qpow( type == 1 ? G : Gi , (P - 1) / (mid << 1)); //Wn = g ^ ((p - 1) / n) (mod p)
for(int j = 0; j < n; j += (mid << 1)) {
ll w = 1;
for(int k = 0; k < mid; k++, w = (w * Wn) % P) {
int x = A[j + k], y = w * A[j + k + mid] % P;
A[j + k] = (x + y) % P,
A[j + k + mid] = (x - y + P) % P;
}
}
}
if(type == -1) {
ll inv = qpow(n, P - 2);
for(int i = 0; i < n; i++) A[i] = A[i] * inv % P;
}
}
void solve(ll *a, ll *b) {
int lim = 1, L = 0;
while(lim <= n + m) lim <<= 1, L++;
for(int i = 0; i < lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
for(int i = n + 1; i < lim; i++) a[i] = 0; //a,b need init
for(int i = m + 1; i < lim; i++) b[i] = 0;
NTT(a, 1, lim); NTT(b, 1, lim);
for(int i = 0; i < lim; i++) a[i] = a[i] * b[i] % P;
NTT(a, -1, lim);
}
int c[N];
void run(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> c[i];
for(int i = 1; i <= n; i++) {
a[c[i]] = (a[c[i]] + qpow(qpow(p, 1ll * c[i] * c[i]), P - 2)) % P;
}
for(int i = 1; i <= n; i++) {
b[c[i]] = a[c[i]];
}
n = m = *max_element(c + 1, c + n + 1) + 1;
solve(a, b);
int ans = 0;
for(int i = 0; i <= 2 * n - 2; i++) {
int res = 1ll * qpow(p, 1ll * i * i) * a[i] % P;
ans = (ans + res) % P;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}
C. 酒馆战棋
贪心即可。
Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 1e3+5,MAXM = 1e6+5,MOD = 1e9+7,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;
int T,n,A,B,C,D;
char s[MAXN];
int solve1(int a,int b,int c,int d){
int ans=0;
for(int i=0;i<n;i++){
if(s[i]=='0'){
if(c + d){
if(d)d--,c++;
}else if(a+b){
if(b)b--,a++;
}
}else{
if(c+d){
if(c)c--,ans++;
else c++,d--;
}else if(a+b){
if(a)a--,ans++;
else b--,a++;
}
}
}
return ans;
}
int solve2(int a,int b,int c,int d){
int ans=0;
for(int i=0;i<n;i++){
if(s[i]=='0'){
if(c + d){
if(!c)d--,c++;
}else if(a+b){
if(!a)b--,a++;
}
}else{
if(c+d){
if(!d)c--,ans++;
else c++,d--;
}else if(a+b){
if(!b)a--,ans++;
else b--,a++;
}
}
}
return ans;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin>>T;
while(T--){
cin>>n>>A>>B>>C>>D;
cin>>s;
cout<<solve1(A,B,C,D)<<' '<<solve2(A,B,C,D)<<'\n';
}
return 0;
}
F. 图与三角形
容斥一下。
通过枚举角算出不合法的三角形个数,然后用总答案减去即可。
最后要除以一个\(2\),因为一个三角形不合法,就会存在两个角的两边不同色。
Code
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define REPE(i,a,b) for(int i=(a); i<=(b); i++)
#define MAXN 5007
typedef long long ll;
typedef unsigned long long ull;
int rc[MAXN], bc[MAXN];
ull ans;
int main() {
memset(rc,0,sizeof rc);
memset(bc,0,sizeof bc);
int n; scanf("%d", &n);
int A,B,C,P,D; scanf("%d%d%d%d%d", &A, &B, &C, &P, &D);
REPE(i,1,n) REPE(j,i+1,n) {
if(((ll)A*(i+j)*(i+j)+(ll)B*(i-j)*(i-j)+C)%P>D) {
bc[i]++, bc[j]++;
} else {
rc[i]++, rc[j]++;
}
}
ans=0;
REPE(i,1,n) {
ans+=bc[i]*rc[i];
}
ans/=2;
ans = (ull)n*(n-1)*(n-2)/6-ans;
printf("%llu\n", ans);
}
G. 单调栈
显然若\(f(1)\)一定为\(1\),对于所有\(f\)值相同的位置,我们依次从小到大倒序来放置即可。
然后将所有的\(f\)值减一,再重复执行以上操作即可。
贪心的正确性:
-
\(f(1)=1\)显然,然后对于所有为\(1\)的位置,若存在\(i,j,i<j\),有\(a_i<a_j\),那么必然\(f_i<f_j\),所以必然是倒序。因为要求字典序最小,所以依次放置。
-
对于多个\(f=-1\),因为字典序最小,我们能不处理则不处理,否则会使前面的增大。
代码如下:
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/17 20:53:27
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 100 + 5;
int n;
int f[N], ans[N];
bool chk[N];
void run(){
memset(chk, 0, sizeof(chk));
int Min = 1;
cin >> n;
for(int i = 1; i <= n; i++) cin >> f[i];
while(1) {
int fir = -1;
for(int i = 1; i <= n; i++) {
if(!chk[i]) {
if(f[i] == -1) f[i] = 1;
fir = i; break;
}
}
if(fir == -1) break;
for(int i = n; i >= 1; i--) if(!chk[i]) {
if(f[i] == 1) {
chk[i] = true;
ans[i] = Min++;
} else if(f[i] > 1) {
f[i] -= 1;
}
}
}
for(int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
H. 异或询问
题意:
给出一个序列\(a_{1...n}\),定义\(f(x)\)为有几个\(a_i\)小于等于\(x\)。
现有\(q\)个询问,每次给定\(l,r,x\),需要求\(\displaystyle\sum_{i=l}^rf^2(i\ xor\ x)\)。
思路:
- 显然可以将询问拆为两个前缀相减,那么现在只需要考虑求\(\sum_{i=0}^rf^2(i\ xor\ x)\)。
- 因为\(i\)的变化为\(0\rightarrow r\),我们可以类似于数位\(dp\)那样来考虑:假设当前\(r\)最高位为\(w\),也就是说\(bit(r,w)=1\),那么这位取\(0\)的话,后面可以任意取,所以\(i\ xor\ r\)此时为连续的一段区间;如果这一位取\(1\),那么就枚举下一位再类似考虑就行。
- 也就是说我们按二进制位从高到低考虑,将\(i\ xor\ x,0\leq i\leq r\)可以拆分为若干个连续的区间,接下来考虑的就是怎么求\(\sum_{i=l}^rf(i)\)。
- 这个就很好求了,直接预处理后二分即可。
细节见代码:
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/19 11:47:00
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5, MOD = 998244353;
int n, q;
int a[N];
vector <pii> b;
ll pre[N], w[N];
int sum(int x) {
int p = upper_bound(all(b), MP(x, INF)) - b.begin() - 1;
if(p < 0) return 0;
return ((p > 0 ? pre[p - 1] : 0) + 1ll * (x - b[p].fi + 1) * w[p] % MOD) % MOD;
}
int solve(int n, int x) {
int res = 0;
for(int i = 29; i >= 0; i--) {
if(n >> i & 1) {
int t = (n ^ x) >> i << i;
int st = t ^ (1 << i);
int ed = st + (1 << i) - 1;
res = (1ll * res + sum(ed) - sum(st - 1) + MOD) % MOD;
}
}
int t = n ^ x;
res = (1ll * res + sum(t) - sum(t - 1) + MOD) % MOD;
return res;
}
void run() {
for(int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
for(int i = 1, j; i <= n; i = j + 1) {
j = i;
while(j < n && a[j + 1] == a[j]) ++j;
b.push_back(MP(a[i], j - i + 1));
}
for(int i = 0; i < sz(b); i++) {
if(i == 0) w[i] = b[i].se;
else w[i] = w[i - 1] + b[i].se;
}
for(int i = 0; i < sz(b); i++) {
w[i] = 1ll * w[i] * w[i] % MOD;
}
for(int i = 0; i < sz(b); i++) {
if(i + 1 < sz(b)) {
if(i == 0) pre[i] = 1ll * (b[i + 1].fi - b[i].fi) * w[i] % MOD;
else pre[i] = (pre[i - 1] + 1ll * (b[i + 1].fi - b[i].fi) * w[i] % MOD) % MOD;
}
}
while(q--) {
int l, r, x; cin >> l >> r >> x;
int ans = (solve(r, x) - solve(l - 1, x) + MOD) % MOD;
cout << ans << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n >> q) run();
return 0;
}
I. 变大!
题意:
给出一个序列\(a[1...n]\),每次可以选择一个\(i(2\leq i<n)\),然后将\(a[i-1],a[i],a[i+1]\)都变为\(max(a[i-1],a[i],a[i+1])\)。
现在进行\(k\)次这样的操作,目标是最大化\(\sum_{i=1}^n a_i\)。
现在对于\(k=1...n\)依次输出最终答案。
\(n\leq 100\)。
思路:
显然最后的答案都是一段一段的形式,每一段的值都为该段最大值。
然后还有一个性质:
- 对于长度为\(l\)的一段区间,需要将其全变为最大值的操作次数为\(\lfloor\frac{l}{2}\rfloor\)。
那么我们枚举每个数,再枚举其分段,然后做个简单\(dp\)就行了。
时间复杂度\(O(n^3)\)。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/17 21:24:13
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 50 + 5, M = 20 + 5;
int n;
int a[N];
int dp[N][N];
void run(){
memset(dp, 0, sizeof(dp));
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
int mx = a[i];
for(int j = i; j >= 1; j--) {
mx = max(mx, a[j]);
int c = (i - j + 1) / 2;
for(int k = c; k <= n; k++) {
dp[i][k] = max(dp[i][k], dp[j - 1][k - c] + (i - j + 1) * mx);
}
}
}
for(int i = 1; i <= n; i++) cout << dp[n][i] << " \n"[i == n];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
J. K重排列
题意:
对于一个排列\(p[1\cdots n]\),设\(p^k[i]=p[p^{k-1}[i]]\),且\(p^1[i]=p[i]\)。
如果存在一个\(k\),使得对于所有的\(i\)都有\(p^k[i]=i\),那么\(k\)为\(p\)的一个周期。
最后统计满足\(k\)为其一个周期的排列个数。
思路:
题解已经说的很清楚了,在比赛的时候考虑的是将\(n\)个点划分为若干个循环,每个循环的长度整除\(k\)。
然后想的是直接搜索,感觉问题应该不大...
直接附上题解说的吧。
给出暴力的代码:
Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 50+5,MAXM = 1e6+5,MOD = 998244353,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;
int n,T;
ll ans=0,K,fact[MAXN],inv[MAXN];
ll qpow(ll a,ll b){
ll ans=1;
for(;b;b>>=1,a=a*a%MOD)if(b&1)ans=ans*a%MOD;
return ans;
}
ll C(int a,int b){
if(a<b)return 0;
if(a==b || b==0)return 1;
return fact[a] * inv[a-b]%MOD*inv[b]%MOD;
}
void dfs(int sum,int pre,ll res,int cnt){
if(!sum){
res = res * inv[cnt]%MOD;
ans = (ans + res)%MOD;
//cout<<cnt<<' '<<res<<'\n';
return ;
}
for(int i=pre;i<=sum;i++){
if(K%i==0){
//cout<<sum<<' '<<i<<' '<<C(sum,i)<<'\n';
ll tmp = res * C(sum,i)%MOD*fact[i-1]%MOD;
if(i != pre){
tmp = tmp * inv[cnt] % MOD;
dfs(sum-i,i,tmp,1);
}else dfs(sum-i,i,tmp,cnt+1);
}
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
fact[1] = fact[0] = 1;
for(int i=2;i<=50;i++)fact[i] = fact[i-1]*i%MOD;
inv[50] = qpow(fact[50],MOD-2);
for(int i=49;i>0;i--)inv[i] = inv[i+1]*(i+1)%MOD;
inv[0]=1;
cin>>T;
while(T--){
cin>>n>>K;
ans = 0;
dfs(n,1,1,0);
cout<<ans<<'\n';
}
return 0;
}
K. 最大权值排列
接下来签到四连。
Code
/*
* Author: heyuhhh
* Created Time: 2020/1/17 13:32:46
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
int n;
void run(){
int now = 1;
for(int i = 1; i <= n; i++) {
cout << now << ' ';
if(i <= (n - 1) / 2) now += 2;
else {
if(now & 1) {
if(n & 1) --now;
else ++now;
}
else now -= 2;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
L. 你吓到我的马了.jpg
BFS。
Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 1e2+5,MAXM = 1e6+5,MOD = 1e9+7,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;
int n,m;
int dx[8] = {-2,-2,2,2,-1,1,-1,1};
int dy[8] = {-1,1,-1,1,-2,-2,2,2};
int dx2[8] = {-1,-1,1,1,0,0,0,0};
int dy2[8] = {0,0,0,0,-1,-1,1,1};
char mp[MAXN][MAXN];
int vis[MAXN][MAXN];
inline bool bound(int x,int y){
return x>=1&&x<=n&&y>=1&&y<=m;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>(mp[i]+1);
}
int sx,sy;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]=='M'){
sx = i,sy=j;
}
}
}
queue<pii> q;
q.push({sx,sy});
vis[sx][sy] = 1;
pii nw;
//cout<<sx<<' '<<sy<<'\n';
while(!q.empty()){
pii a = q.front();q.pop();
for(int i=0;i<8;i++){
nw.x = a.x + dx[i];
nw.y = a.y + dy[i];
if(bound(nw.x,nw.y) && mp[a.x+dx2[i]][a.y+dy2[i]]!='X' && mp[nw.x][nw.y] != 'X' && !vis[nw.x][nw.y]){
q.push(nw);
vis[nw.x][nw.y] = vis[a.x][a.y] + 1;
//cout<<nw.x<<' '<<nw.y<<' '<<vis[nw.x][nw.y]<<'\n';
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(vis[i][j])cout<<vis[i][j]-1<<" \n"[j==m];
else cout<<"-1"<<" \n"[j==m];
}
}
return 0;
}
M. 自闭
模拟。
Code
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define G0(x) memset(x,0,sizeof(x))
#define MAXN 107
bool sub[MAXN];
bool ac[MAXN][17];
int acc[MAXN];
int was[MAXN][17];
int wac[MAXN][17];
int accnt[17];
int zb[MAXN];
int n,m,W;
int main() {
scanf("%d%d%d", &n, &m, &W);
G0(sub),G0(ac),G0(was),G0(wac),G0(accnt),G0(zb),G0(acc);
REP(i,0,W) {
int x,y,c; scanf("%d%d%d", &x, &y, &c); x--,y--;
sub[x]=1;
if(c) {
if(!ac[x][y]) accnt[y]++,ac[x][y]=1,acc[x]++;
wac[x][y]=0;
} else {
wac[x][y]++;
was[x][y]=max(was[x][y],wac[x][y]);
}
}
REP(i,0,n) {
if(!sub[i]) {
zb[i]=998244353;
continue;
} else if(!acc[i]) {
zb[i]=1000000;
continue;
} else if(acc[i]==m) {
zb[i]=0;
continue;
}
REP(j,0,m) {
if(!ac[i][j] && accnt[j]>0) {
zb[i]+=20;
}
if(!ac[i][j] && accnt[j]>=n/2) {
zb[i]+=10;
}
zb[i]+=was[i][j]*was[i][j]*((!ac[i][j])+1);
}
}
REP(i,0,n) {
printf("%d\n", zb[i]);
}
}
N. 合并!
稍微手模一下就可以发现怎么合并答案都是一样。
Code
/*
* Author: heyuhhh
* Created Time: 2020/1/17 13:05:18
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2000 + 5;
int n;
int a[N];
void run(){
for(int i = 1; i <= n; i++) cin >> a[i];
ll ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = i + 1; j <= n; j++) {
ans += a[i] * a[j];
}
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
重要的是自信,一旦有了自信,人就会赢得一切。