poj 3378

连续三场吃蛋,感觉压力好大,总结一下,首先英语不好,读题比较吃力,这一点正在努力改变,其次思维有点死了,脑袋里想到一个方法就狂敲,结果狂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;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值