连续三场吃蛋,感觉压力好大,总结一下,首先英语不好,读题比较吃力,这一点正在努力改变,其次思维有点死了,脑袋里想到一个方法就狂敲,结果狂wa,程序越改越乱,心墙也会随着变化,每次去比赛就是想着不吃蛋,心里压力较大,还有自身代码写的太多bug了,经常wa,每次提交都是一次失望,想想这样20+次会怎么样,主要是卡题的心情,会影响做题的心情,事后只能悔恨这题能出的,回来就a了,看榜会影响心请,但是别人过的题你又觉得自己能过,就是这么纠结,反正就是打比赛的心态很不好,以后要经常锻炼自己的心态,得失心要平稳住。
这题是我比赛的题,当时见到有人过就去做了,结果就是wa,当时一直不明白为什么wa,没遇到过爆longlong的再说有人过了那么快,没太在意是爆了longlong,改成longlong去交,还是wa,就这里开始蛋疼了,后面有题并查集又是写烂了,一直wa,后面才知道人家都用dfs写的,现在觉得有点亏了,这题当晚回来用高精度还是wa,一直不知道错在哪,今天在看看代码,发现高精度函数的变量写成了int,改后一交,果断a了。程序就是这样,很容易就犯错,所以要提高自己的代码能力,回去反思了,这题和前面我的那题树状数组一样,建议先去看那篇树状数组+dp,这里只要注意高进度和longlong
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
long long dp[50005][6];
int mac,c[50005],sum[1000]={0},len=1;
const int maxn=1000;
struct nd
{
int x,y;
};
int cmp(nd a,nd b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
void add(long long n)
{
int b[1000]={0},a[1000]={0};
int i=0;
while(n)
{
a[i++]=n%10;
n/=10;
}
for(i=0;i<100;i++)
{
b[i]=a[i]+sum[i]+b[i];
if(b[i]>=10)
{
b[i+1]++;
b[i]%=10;
}
}
for(i=0;i<100;i++)
sum[i]=b[i];
}
int bit(int n)
{
return n&(-n);
}
long long count(int n,int j)
{
long long ans=0;
while(n)
{
ans+=dp[n][j];
n-=bit(n);
}
return ans;
}
void update(int n,int j,long long k)
{
while(n<=mac)
{
dp[n][j]+=k;
n+=bit(n);
}
}
void DP(int n)
{
long long tem;
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
len=1;
int i,j;
for(i=1;i<=n;i++)
{
tem=count(c[i]-1,3);
add(tem);
for(j=3;j>0;j--)
{
tem=count(c[i]-1,j-1);
update(c[i],j,tem);
}
update(c[i],0,1);
}
len=100;
while(sum[len]==0&&len>0)
len--;
for(i=len;i>=0;i--)
printf("%d",sum[i]);
printf("\n");
}
int main()
{
int i,n;
nd s[50005];
while(scanf("%d",&n)!=EOF)
{
mac=n;
for(i=1;i<=n;i++)
{
scanf("%d",&s[i].x);
s[i].y=i;
}
sort(s+1,s+1+n,cmp);
int k=1;c[s[1].y]=1;
for(i=1;i<=n;i++)
{
if(s[i].x==s[i-1].x)
c[s[i].y]=c[s[i-1].y];
else
c[s[i].y]=k++;
}
DP(n);
}
return 0;
}