啊 真的挂了 csp再挂就不行了啊

现在普及组的题都挂不到1=了

不能颓废qaq

T1 [NOIP2013 普及组] 表达式求值

https://www.luogu.com.cn/problem/P1981

qaq 炸了 分炸没了

因为前几天写了个表达式的题目就转了后缀表达式求

真香了 char cnt= 0 还tm的是错过的地方

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define Mod 10000
const int N= 1000005;         //注意题目中的数据范围是 表达式中加法运算符和乘法运算符的总数≤100000 但是真实情况的话还有数字
struct Node
{
	int val;
	int is;
};
int num[N], top; 
Node fu[N]; int tot;
char ans[N]; int cnt;      //char cnt qaq    update 2021.10.5 已更正

signed main()
{
	string s; cin>> s;
	for(int i=0; i<s.size(); i++)
	{
		if(s[i]== '*') ans[++ cnt]= s[i];
		if(s[i]== '+')
		{
			while(ans[cnt]== '*') fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1;
			ans[++ cnt]= '+';
		}
		if(s[i]>= '0'&& s[i]<= '9')
		{
			int x= 0;
			while(s[i]>= '0'&& s[i]<= '9') x= (x* 10+ s[i]- '0')% Mod, i++;
			i-- ;
			fu[++ tot].val= x;
		}
	}
	while(cnt) fu[++ tot].val= ans[cnt-- ], fu[tot].is= 1;                    //转后缀表达式
	for(int i=1; i<=tot; i++)
	{
		if(fu[i].is== 0) num[++ top]= fu[i].val;
		else 
		{
			int a= num[top-- ]; int b= num[top-- ];
			if(fu[i].val== 43) num[++ top]= (a+ b)% Mod;
			else num[++ top]= (a* b)% Mod;
		}
	}                                                 //直接求值
	cout<< num[1]% Mod<< endl;
	
	return 0;
}                                    //我可能是最麻烦的方法了 其实这题并不用那么多 直接能乘就乘 能加就加好了

[NOIP2013 普及组] 小朋友的数字

https://www.luogu.com.cn/problem/P1982

小朋友的题都不会做了啊

怎么说 自己坑自己?

考场上发现了会爆long long然后作茧自缚 写得不对???

原来有80pts的直接挂掉了

好在写了个50pts的部分分

80pts (会爆long long) 虽然写的是P50但有80pts

struct P50
{
	int a[N], f[N], t[N], h[N];
	void solve()
	{
	    for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
	    f[1]= a[1], t[1]= a[1];
	    for(int i=2; i<=n; i++)
	    {
		   f[i]= max(f[i- 1]+ a[i], a[i]);
		   t[i]= max(t[i- 1], f[i]);
	    }                                                  //dp求最大连续字段和 其实t数组就是个摆设, f数组也没啥用
	    h[1]= t[1]; 
	    int maxn= -INF; maxn= max(maxn, h[1]+ t[1]); 
	    for(int i=2; i<=n; i++)  
	    {
		   h[i]= maxn;
		   maxn= max(maxn, h[i]+ t[i]);
	    }
	    maxn= -INF;
	    for(int i=1; i<=n; i++) maxn= max(maxn, h[i]);           //模拟题
	    if(maxn< 0) 
		{
			cout<< '-';
			maxn= abs(maxn);
		}                             //听说还有-0什么的 不过没卡
	    cout<< maxn% p<< endl;
	}
}P50;

发现要写高精 懒得写 怎么办呢 错误的代码:


//其实可以发现就是上面的代码加上两个函数2333
//不要怀疑 因为我就是这样改的

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define INF (int)1e18
const int N= 1000005;
struct Node
{
	int s; int y;
}a[N], f[N], t[N], h[N];  

int n, p; 

Node add(Node a, Node b)
{
	Node c; c.s= a.s+ b.s;
	c.y= a.y+ b.y; if(c.y/ p!= 0) c.s+= c.y/ p, c.y%= p;
	return c;
}

Node Max(Node a, Node b)
{
	if(a.s> b.s) return a;
	else if(a.s< b.s) return b;
	else if(a.y> b.y) return a;
	else return b;
}

signed main()
{
	cin>> n>> p;
	for(int i=1; i<=n; i++) 
	{
		int x; scanf("%lld", &x);
		a[i].s= x/ p; a[i].y= x% p;        
	}
	f[1]= a[1], t[1]= a[1];
	for(int i=2; i<=n; i++)
	{
		f[i]= Max(add(f[i- 1], a[i]), a[i]);
		t[i]= Max(t[i- 1], f[i]);
	}
	h[1]= t[1]; 
	Node maxn; maxn.s= -INF; maxn= Max(maxn, add(h[1], t[1])); 
	for(int i=2; i<=n; i++)  
	{
		h[i]= maxn;
		maxn= Max(maxn, add(h[i], t[i]));
	}
	maxn.s= -INF;
	for(int i=1; i<=n; i++) maxn= Max(maxn, h[i]);
	if(maxn.y< 0)
	{
		cout<< '-';
		maxn.y= abs(maxn.y);
	}
	cout<< maxn.y% p<< endl;
	
	return 0;
}

这是考场上部分代码 剩下的因为太乱和源码丢失就不放了

这是错的 20pts 为什么?

看起来很有道理啊

add太草率了

Node add(Node a, Node b)
{
	Node c; c.s= a.s+ b.s;
	c.y= a.y+ b.y;                  //他炸掉了
	//In this way 
	if(c.s>= 0&& c.y>= p) c.s+= c.y/ p, c.y= c.y% p;           //如果余数同符号 一切都好 
	if(c.s<= 0&& c.y<= -p) c.s+= c.y/ p, c.y= c.y% p;
	if(c.s> 0&& c.y< 0) c.s-- , c.y+= p;               //不然我们不能直接搞 不可能a*p+b然后b是负的吧
	if(c.s< 0&& c.y>= p) c.s++ , c.y-= p;
	return c;
}

莫名其妙地Accept了


还有另外一种写法 智商什么的吊打高精度

不过这种高精度法也可以应用什么的 用于小的高精度 100位什么的不要找我啊qaq

#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N= 1000005;
int a[N], t[N];

signed main()
{
	int n, p; cin>> n>> p;
	for(int i= 1; i<= n; i++ ) scanf("%lld", &a[i]);
	int sum= - (int)1e18;
	for(int i= 1; i<= n; i++ )
	{
		sum= max(sum+ a[i], a[i]);
		t[i]= sum;
	}
	for(int i= 2; i<= n; i++ ) t[i]= max(t[i], t[i- 1]); 
	int flag= 0;
	for(int i= 2; i<= n; i++)
		if(t[i]> abs(t[1])) 
		{
			flag= 1; break;
		}
	if(! flag)
	{
		cout<< t[1]% p<< endl;
		return 0;
	}
	int maxn= 2* t[1]% p;
	for(int i= 3; i<= n; i++ )
	    maxn= (maxn+ max((int)0, t[i- 1]))% p;
    cout<< maxn% p<< endl;
    
    return 0;
}

其实我并没有懂qaq

有dalao能教教我吗qaq


T3

[NOIP2013 普及组] 车站分级

https://www.luogu.com.cn/problem/P1983

真的老题了

但我再次写的是暴力 luogu坑人qaq

正解 不用所有都连边 只要找个中转点就行了

这题虽然邻接矩阵存最好 但我是链式前向星存的

#include <bits/stdc++.h>
using namespace std;
const int N= 2005, M= N* N;
int in[N], h[N], e[M], ne[M], idx;
int dist[N], vis[N];
 
void add(int a, int b)
{
    e[idx]= b, ne[idx]= h[a], h[a]= idx++ ;
    return ; 
}
 
int main()
{
    int n, m; cin>> n>> m;
     
    memset(h, -1, sizeof h);
    for(int i= 1; i<= m; i++ )
    {
        int x; scanf("%d", &x);
        memset(vis, 0, sizeof vis);
        int st= n, ed= 0;
        for(int j= 1; j<= x; j++ )
        {
            int y; scanf("%d", &y); vis[y]= 1;
            add(y, i+ n); in[i+ n]++ ;                  //可能叫找虚点什么的
            st= min(st, y); ed= max(ed, y);
        } 
        for(int j= st; j<= ed; j++ )
        {
            if(vis[j]) continue;
            add(i+ n, j); in[j]++ ;                //存拓扑排序
        } 
    } 
     
    queue<int> q;
    for(int i= 1; i<= n+ m; i++ ) 
       if(! in[i]) q.push(i);
    while(q.size())
    {
        int u= q.front(); q.pop();
        for(int i= h[u]; ~ i; i= ne[i]) 
        {
            int j= e[i];
            dist[j]= max(dist[j], dist[u]+ 1);         //找最长链
            in[j]-- ;
            if(! in[j]) q.push(j);
        }
    } 
    int maxn= 0;
    for(int i= 1; i<= n; i++ ) maxn= max(maxn, dist[i]);
     
    cout<< (maxn+ 1)/ 2+ 1<< endl;
     
    return 0;
}
未来可期。