Codeforces Round #594 (Div. 1)
Preface
这场CF真是细节多的爆炸,B,C,F都是大细节题,每道题都写了好久的说
CSP前的打的最后一场比赛了吧,瞬间凉意满满
希望CSP可以狗住冬令营啊(再狗不住真没了)
A. Ivan the Fool and the Probability Theory
原谅我脑子不如陈指导好想不出来正解,然后打了个暴力3min找到规律做掉了。。。
然后讲一下正确的做法(陈指导教我的):
考虑我们用DP做出\(1\times m\)的矩阵的答案记为\(f_m\),考虑用它填了第一行
然后我们考虑第一行的填法:
- 第一行填的是\(0/1\)相间的,此时方案数有\(2\)种,考虑第二行填的就要么与第一行相同,要么与第一行相反。而且相同的不能连续填两行。我们仔细想想发现这个问题是不是和原来的一样了?(第一行看作某种状态,相反看作另一种状态),那么显然此时的方案数就是\(f_n\)
- 第一行填的是非\(0/1\)相间的,此时方案数有\(f_m-2\)种,显然第二行的填法只有每个与第一行的相反。而且这样的情况要一直延续到第\(n\)行,那么此时的总方案数就是\(f_m-2\)
综上所述,最后的答案就是\(f_n+f_m-2\)
#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005,mod=1e9+7;
int n,m,f[N][2];
inline int sum(CI x,CI y)
{
int t=x+y; return t>=mod?t-mod:t;
}
int main()
{
scanf("%d%d",&n,&m); int lim=max(n,m); RI i;
for (f[1][0]=f[1][1]=1,f[2][0]=f[2][1]=2,i=3;i<=lim;++i)
f[i][0]=f[i-1][1],f[i][1]=sum(f[i-1][0],f[i-1][1]);
return printf("%d",sum(sum(sum(f[n][0],f[n][1]),sum(f[m][0],f[m][1])),mod-2)),0;
}
B. The World Is Just a Programming Task (Hard Version)
真NM烦人(假装有很多细节)的题,中间想了好多假算法的说
考虑我们先判掉必然无解的情况,那么显然这时我们可以搞出一个合法的括号序列
从这个合法的序列开始,我们把它的括号匹配求出来,同时记一个\(ct_i\)表示第\(i\)对括号里面有多少对匹配的括号
我们现在可以进行的交换有哪几类:
- 什么都不干(原地交换),此时的答案就是\(ct_0\)
- 交换某对匹配的括号,而这对括号外面没有其它的括号。我们可以发现此时这个串大概是\(\cdots(ct_i)\cdots\)的样子,因此我们交换后就变成\((\cdots)ct_i\)的样子,显然答案是了\(ct_i+1\)
- 交换某对匹配的括号,而这对括号外面只有一对其它的括号。此时的形式就是\(\cdots(\cdots(ct_i)\cdots)\cdots\),那么交换后就变成\(\cdots(\cdots)ct_i(\cdots)\cdots\)的样子,那么这时候答案就是\(ct_i+ct_0+1\)
- 交换某对匹配的括号,而这对括号外面有多于一对其它的括号。简单分析后答案不会改变
- 交换不匹配的括号,就是个弟弟玩意,显然答案也不会增加
那么这题总算是做完了
#include<cstdio>
#include<queue>
#define RI register int
#define CI const int&
using namespace std;
const int N=600005;
int n,dlt,st,cl,cr,stk[N],top,tot,L[N],R[N],ct[N],out[N],a[N],b[N],pfx[N],ans,x,y; char s[N];
struct heap
{
priority_queue <int,vector <int>,greater <int> > val,del;
inline void insert(CI x)
{
val.push(x);
}
inline void remove(CI x)
{
del.push(x);
}
inline int top(void)
{
while (!val.empty()&&!del.empty()&&val.top()==del.top())
val.pop(),del.pop(); return val.top();
}
}hp;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i,j; for (scanf("%d%s",&n,s+1),i=n+1;i<=(n<<1);++i)
a[i]=a[i-n]=s[i-n]=='('?1:-1,s[i-n]=='('?++cl:++cr;
if (cl!=cr) return puts("0\n1 1"),0;
for (i=1;i<=n;++i) hp.insert(pfx[i]=pfx[i-1]+a[i]);
for (i=1;i<=n;++i)
{
if (hp.top()+dlt>=0) { st=i; break; }
hp.remove(pfx[i]); dlt-=a[i]; hp.insert(0-dlt);
}
for (i=st;i<=st+n-1;++i) b[i-st+1]=a[i];
for (i=1;i<=n;++i) if (b[i]==1) stk[++top]=++tot,L[tot]=i;
else out[stk[top]]=stk[top-1],R[stk[top]]=i,++ct[stk[--top]];
for (ans=ct[0],x=y=i=1;i<=tot;++i)
{
if (!out[i]) { if (ct[i]+1>ans) ans=ct[i]+1,x=L[i],y=R[i]; }
else if (!out[out[i]]) { if (ct[i]+ct[0]+1>ans) ans=ct[i]+ct[0]+1,x=L[i],y=R[i]; }
}
return printf("%d\n%d %d",ans,(x+st-2)%n+1,(y+st-2)%n+1),0;
}
C. Queue in the Train
真是令人头晕脑涨的模拟题,我们直接按题意模拟操作
考虑我们用一些数据结构来维护答案:
- 给原数组按时间第一关键字,序号第二关键字排序,然后把可选每个数进行操作
- 开一个队列表示正在排队的人
- 有些人可能已经可以打水了,但是由于前面有人再它前面排队,因此它不会去打水。那么我们需要一个堆来维护这些人的编号
- 怎么判掉堆顶能不能去打水呢,我们再开一个
set
用来动态维护队列里正在排队的人的编号,每次用堆顶和set
里的最小值比较即可
注意这些操作维护的顺序以及各种各样的细节
#include<cstdio>
#include<algorithm>
#include<queue>
#include<set>
#define RI register int
#define CI const int&
#define int long long
using namespace std;
const int N=100005;
struct data
{
int val,id;
friend inline bool operator < (const data& A,const data& B)
{
return A.val<B.val||(A.val==B.val&&A.id<B.id);
};
}a[N],t[N]; int n,p,ans[N],cnt; queue <int> q;
set <int> s; priority_queue <int, vector <int>, greater <int> > hp;
signed main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i,j,pos; for (scanf("%I64d%I64d",&n,&p),i=1;i<=n;++i)
scanf("%I64d",&a[i].val),a[i].id=i; sort(a+1,a+n+1);
int cur=0; for (i=pos=1;i<=n;++i)
{
if (hp.empty()&&q.empty()&&pos<=n)
q.push(a[pos].id),s.insert(a[pos].id),cur=a[pos].val,++pos;
while (!hp.empty()) if (s.empty()||hp.top()<*s.begin())
q.push(hp.top()),s.insert(hp.top()),hp.pop(); else break; cur+=p;
while (pos<=n&&a[pos].val<=cur) t[++cnt]=a[pos++];
for (j=1;j<=cnt;++j) if (s.empty()||t[j].id<*s.begin())
q.push(t[j].id),s.insert(t[j].id); else hp.push(t[j].id);
ans[q.front()]=cur; s.erase(q.front()); q.pop(); cnt=0;
}
for (i=1;i<=n;++i) printf("%I64d ",ans[i]); return 0;
}
D. Catowice City
比B,C都清新的思维题,还算是帮CSP复习了一波板子
考虑由于每对人和猫都要作出选择,那么如果我们有人\(i\)和猫\(j\)的边,那么说明选了人\(i\)就必须选人\(j\)(除去与自己猫的边)
那么我们可以把这种关系看成一条有向边,那么容易发现SCC里的点都是互相依赖的,选了一个其它的都要选
那么我们先Tarjan缩点,然后如果最后的图就是一个联通块,那么显然是无解的
否则我们考虑找出一个度数为\(0\)的联通块,把这个联通块里的点选作人,其它的点都选做猫即可
#include<cstdio>
#include<iostream>
#define RI register int
#define CI const int&
using namespace std;
const int N=1000005;
struct edge
{
int to,nxt;
}e[N]; int t,head[N],n,m,cnt,x,y,ans1[N],c1,ans2[N],c2;
int dfn[N],low[N],idx,col[N],stk[N],top,deg[N],scc; bool vis[N];
inline void clear(void)
{
RI i; for (i=1;i<=n;++i) head[i]=dfn[i]=low[i]=deg[i]=0;
cnt=scc=top=c1=c2=0;
}
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt;
}
#define to e[i].to
inline void Tarjan(CI now)
{
dfn[now]=low[now]=++idx; vis[stk[++top]=now]=1;
for (RI i=head[now];i;i=e[i].nxt)
if (!dfn[to]) Tarjan(to),low[now]=min(low[now],low[to]);
else if (vis[to]) low[now]=min(low[now],dfn[to]);
if (dfn[now]==low[now])
{
for (col[now]=++scc,vis[now]=0;stk[top]!=now;--top)
col[stk[top]]=scc,vis[stk[top]]=0; --top;
}
}
int main()
{
for (scanf("%d",&t);t;--t)
{
RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=m;++i)
scanf("%d%d",&x,&y),x!=y&&(addedge(x,y),0);
for (i=1;i<=n;++i) if (!dfn[i]) Tarjan(i);
if (scc==1) { puts("No"); clear(); continue; }
for (j=1;j<=n;++j) for (i=head[j];i;i=e[i].nxt)
if (col[j]!=col[to]) ++deg[col[j]];
int id; for (i=1;i<=scc;++i) if (!deg[i]) { id=i; break; }
for (i=1;i<=n;++i) if (col[i]==id) ans1[++c1]=i; else ans2[++c2]=i;
puts("Yes"); printf("%d %d\n",c1,c2);
for (i=1;i<=c1;++i) printf("%d%c",ans1[i]," \n"[i==c1]);
for (i=1;i<=c2;++i) printf("%d%c",ans2[i]," \n"[i==c2]); clear();
}
return 0;
}
E. Turtle
思维难度较大的一道题,写到一半瞄了一眼陈指导的题解才会做
首先我们容易发现第一行的数必须是不降排序的,而第二行的数也要是不升的,证明非常简单,这里不再赘述
我们接下来考虑最大的路径是怎么走的,我们发现我们可以根据路径向下走的位置给它分类,例如我们设\(f(x)=\sum_{i=1}^n a_{1,i}=\sum_{i=p}^n a_{2,i}\)
那么我们考虑一个结论,当\(f(x)\)取\(\max\)时\(x=1\)或\(x=n\),证明如下:
当\(x\not = 1\)且\(x\not =n\)时,设\(f(x)\)为\(\max\)
\(f(x)=f(x-1)+a_{1,x}-a_{2,x-1}\)且\(f(x)\ge f(x-1)\)得出\(a_{1,x}-a_{2,x-1}\ge 0\)
同理对于\(f(x)\)与\(f(x+1)\)也有同样的分析,那么\(-a_{1,x+1}+a_{2,x}\ge 0\)
将不等式两边相加,得到\((a_{1,x}-a_{1,x+1})+(a_{2,x}-a_{2,x-1})\ge 0\),这显然与\(a_1\)不降与\(a_2\)不升矛盾,因此原命题得证
因此我们只需要让\(f(1)\)与\(f(n)\)尽量小即可,贪心地想把两个都要经过的起点终点选上最小值和次小值,考虑剩下的怎么填
由于总和确定,那么我们只要尽量使剩下数的分成两组,和最接近即可
考虑用DP算出答案,我们设\(f_{i,j,k}\)表示前\(i\)个数选了\(j\)个和为\(k\)能否达成,然后用bitset
可以优化掉一维
那么知道答案怎么构造方案呢,发现数据中\(n\)非常小,因此我们可以用meet in middle构造一组解,状态的话状压一下就可以存了
#include<cstdio>
#include<bitset>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#define RI register int
#define CI const int&
using namespace std;
typedef long long LL;
const int N=27,S=50005;
int n,a[N<<1],ans[2][N],ret,cur=1e9;
long long g[N][N*S]; bitset <N*S> f[N]; bool vis[N<<1];
inline bool cd(CI x,CI y)
{
return x>y;
}
inline void DFS1(CI nw,CI lim,CI cs=0,CI sum=0,const LL& sts=0)
{
if (nw>lim) return (void)(g[cs][sum]=sts);
DFS1(nw+1,lim,cs,sum,sts); DFS1(nw+1,lim,cs+1,sum+a[nw],sts|(1LL<<nw));
}
inline void DFS2(CI nw,CI lim,CI cs=0,CI sum=0,const LL& sts=0)
{
if (nw>lim)
{
if (cur-sum>=0&&~g[n-1-cs][cur-sum])
{
RI i,c=1; for (i=3;i<=(n<<1);++i)
if ((g[n-1-cs][cur-sum]>>i)&1LL) ans[0][++c]=a[i],vis[i]=1;
for (i=3;i<=(n<<1);++i)
if ((sts>>i)&1LL) ans[0][++c]=a[i],vis[i]=1;
for (c=0,i=3;i<=(n<<1);++i) if (!vis[i]) ans[1][++c]=a[i];
sort(ans[0]+1,ans[0]+n+1); sort(ans[1]+1,ans[1]+n+1,cd);
for (i=1;i<=n;++i) printf("%d%c",ans[0][i]," \n"[i==n]);
for (i=1;i<=n;++i) printf("%d%c",ans[1][i]," \n"[i==n]);
exit(0);
}
return;
}
DFS2(nw+1,lim,cs,sum,sts); DFS2(nw+1,lim,cs+1,sum+a[nw],sts|(1LL<<nw));
}
int main()
{
RI i,j; for (scanf("%d",&n),i=1;i<=n;++i) scanf("%d",&a[i]);
for (i=n+1;i<=(n<<1);++i) scanf("%d",&a[i]);
sort(a+1,a+(n<<1)+1); ans[0][1]=a[1]; ans[1][n]=a[2];
for (f[0][0]=1,i=3;i<=(n<<1);++i)
for (ret+=a[i],j=min(n-1,i-2);j;--j) f[j]|=(f[j-1]<<a[i]);
for (i=0;i<=ret;++i) if (f[n-1][i])
if (max(i,ret-i)<cur) cur=max(i,ret-i);
return memset(g,-1,sizeof(g)),DFS1(3,n+1),DFS2(n+2,n<<1),0;
}
F. Swiper, no swiping!
细节超级多的分类讨论题,写了一天最后偷来了错掉的数据才过掉
考虑把点按\(\mod 3\)的余数分为三类,记为\(Z,A,B\)
- 如果有\(Z\)类的点,显然我们只用保留一个就可以了(SP:除了只有一个点的情况)
- 如果\(A\)类的点之间有边相连,那么显然只用保留一对这样的点就可以了(SP:除了只有两个点相连的情况)
- 如果B类点之间有环,那么我们可以搜出一个最短的环保留即可(SP:除了整张图就是一个大环的情况)
- 如果存在两个即以上的\(A\)类点,那么我们显然可以找出一条连接两个\(A\)类点的边,满足这两点之间只有\(B\)类点(SP:除了整张图是一条链的情况)
- 除去上面的情况那么现在我们的图一定只有一个\(A\)类点,然后剩下的\(B\)类点构成了森林。那么我们找出两个子树,从里面找出包含\(A\)的两个环即可(SP:除了整张图就是一个节点套上两个环的情况)
大体思路就是这样,关于一些原理的证明可以看官方题解:
然后就做完了,看了题解觉得很简单,写了代码就会很绝望……
#include<cstdio>
#include<vector>
#define RI register int
#define CI const int&
using namespace std;
const int N=500005;
struct edge
{
int to,nxt;
}e[N<<1]; int t,n,m,x[N],y[N],head[N],cnt,fa[N],deg[N],tim[N],cur,ans;
bool ext[N],flag; vector <int> v[N]; int q[N],pre[N],dep[N],vis[N];
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt;
e[++cnt]=(edge){x,head[y]}; head[y]=cnt;
}
inline void paint(CI s,CI t)
{
for (int nw=t;~nw;nw=pre[nw]) ext[nw]=1;
}
#define to e[i].to
inline void findcircle(CI now,CI tc)
{
if (flag) return; RI i; vis[now]=1; tim[now]=tc; int pos,cur=-1;
for (i=head[now];i;i=e[i].nxt)
if (vis[to]==1&&to!=pre[now]&°[to]%3==2)
if (dep[to]>cur) cur=dep[to],pos=to;
if (~cur)
{
for (int x=now;x!=pos;x=pre[x]) ext[x]=1;
flag=1; ext[pos]=1; return;
}
for (i=head[now];i;i=e[i].nxt) if (!vis[to]&°[now]%3==2)
pre[to]=now,dep[to]=dep[now]+1,findcircle(to,tc); vis[now]=2;
}
inline void BFS1(CI st)
{
RI H=0,T=1,i; for (i=1;i<=n;++i) pre[i]=0;
pre[q[T]=st]=-1; while (H<T)
{
int now=q[++H]; if (now!=st&°[now]%3==1) return paint(st,now);
for (i=head[now];i;i=e[i].nxt)
if (!pre[to]) pre[to]=now,q[++T]=to;
}
}
inline void BFS2(CI st)
{
RI H=0,T=1,i; for (i=1;i<=n;++i) pre[i]=0;
pre[q[T]=st]=-1; while (H<T)
{
int now=q[++H]; if (now!=st&&vis[now]) return paint(st,now);
for (i=head[now];i;i=e[i].nxt)
if (!pre[to]) pre[to]=now,q[++T]=to;
}
}
#undef to
inline void output(void)
{
RI i; for (puts("Yes"),ans=0,i=1;i<=n;++i) if (!ext[i]) ++ans;
for (printf("%d\n",ans),i=1;i<=n;++i)
if (!ext[i]) printf("%d ",i); putchar('\n');
}
inline void clear(void)
{
for (RI i=1;i<=n;++i) head[i]=deg[i]=ext[i]=vis[i]=dep[i]=0,v[i].clear(); cnt=cur=flag=0;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
for (scanf("%d",&t);t;--t)
{
RI i,j; for (scanf("%d%d",&n,&m),i=1;i<=m;++i)
scanf("%d%d",&x[i],&y[i]),++deg[x[i]],++deg[y[i]];
if (n==1) { puts("No"); continue; }
for (i=1;i<=n;++i) if (deg[i]%3==0)
{
ext[i]=flag=1; break;
}
if (flag) { output(); clear(); continue; }
if (n==2) { puts("No"); clear(); continue; }
for (i=1;i<=m;++i) if (deg[x[i]]%3==1&°[y[i]]%3==1)
{
ext[x[i]]=ext[y[i]]=flag=1; break;
}
if (flag) { output(); clear(); continue; }
int ct1,ct2=0; for (i=1;i<=n;++i) if (deg[i]==2) ++ct2;
if (ct2==n) { puts("No"); clear(); continue; }
for (i=1;i<=m;++i) if (deg[x[i]]%3==2&°[y[i]]%3==2) addedge(x[i],y[i]);
for (i=1;i<=n;++i) pre[i]=0; for (i=1;i<=n;++i)
if (deg[i]%3==2&&!vis[i]) findcircle(i,++cur);
if (flag) { output(); clear(); continue; }
for (ct1=ct2=0,i=1;i<=n;++i) ct1+=(deg[i]==1),ct2+=(deg[i]==2);
if (ct1==2&&ct2==n-2) { puts("No"); clear(); continue; }
for (ct1=0,i=1;i<=n;++i) if (deg[i]%3==1) ++ct1;
if (ct1>=2)
{
for (i=1;i<=m;++i) if (deg[x[i]]%3!=2||deg[y[i]]%3!=2) addedge(x[i],y[i]);
for (i=1;i<=n;++i) if (deg[i]%3==1) { ct1=i; break; }
BFS1(ct1); output(); clear(); continue;
}
for (i=1;i<=n;++i) if (deg[i]%3==1) { ct1=i; break; }
for (ct2=0,i=1;i<=n;++i) ct2+=(deg[i]%3==2);
if (deg[ct1]==4&&ct2==n-1) { puts("No"); clear(); continue; }
for (i=1;i<=n;++i) vis[i]=0;
for (i=1;i<=m;++i)
{
if (x[i]==ct1) v[tim[y[i]]].push_back(y[i]),vis[y[i]]=1;
if (y[i]==ct1) v[tim[x[i]]].push_back(x[i]),vis[x[i]]=1;
}
for (ct2=0,ext[ct1]=1,i=1;i<=cur;++i) if (v[i].size()>=2)
{
BFS2(v[i][0]); if (++ct2==2) break;
}
output(); clear();
}
return 0;
}
Postscript
不说什么了,各路神仙保我CSP RP++++RP
Codeforces Round #594 (Div. 1)的更多相关文章
- Codeforces Round #594 (Div. 2)
传送门 C. Ivan the Fool and the Probability Theory 题意: 给出一个\(n*m\)的方格,现在要给方格中的元素黑白染色,要求任一颜色最多有一个颜色相同的格子 ...
- Codeforces Round #594 (Div. 1) D. Catowice City 图论
D. Catowice City In the Catowice city next weekend the cat contest will be held. However, the jury m ...
- Codeforces Round #594 (Div. 1) C. Queue in the Train 模拟
C. Queue in the Train There are
- Codeforces Round #594 (Div. 1) D2. The World Is Just a Programming Task (Hard Version) 括号序列 思维
D2. The World Is Just a Programming Task (Hard Version) This is a harder version of the problem. In ...
- Codeforces Round #594 (Div. 2) B. Grow The Tree 水题
B. Grow The Tree Gardener Alexey teaches competitive programming to high school students. To congrat ...
- Codeforces Round #594 (Div. 2) A. Integer Points 水题
A. Integer Points DLS and JLS are bored with a Math lesson. In order to entertain themselves, DLS to ...
- Codeforces Round #594 (Div. 1) A. Ivan the Fool and the Probability Theory 动态规划
A. Ivan the Fool and the Probability Theory Recently Ivan the Fool decided to become smarter and stu ...
- B. Grow The Tree Codeforces Round #594 (Div. 2)
Gardener Alexey teaches competitive programming to high school students. To congratulate Alexey on t ...
- Codeforces Round #594 (Div. 2)(A/B/C)
A. Integer PointsDescription DLS and JLS are bored with a Math lesson. In order to entertain themsel ...
随机推荐
- C language bit byte and word
bit:The smallest storage unit of a computer byte:Common computer storage unit word:Computer natural ...
- JavaWeb 错误/异常时页面提示
经常我们会遇到发生页面404错误,服务器 500 异常,如果默认方式处理,则是将异常捕获之后跳到 Tomcat 缺省的异常页面,如下图所示.
- iOS---------金额转大写
-(NSString *)digitUppercase:(NSString *)numstr{ double numberals=[numstr doubleValue]; NSArray *numb ...
- Vue项目中使用jquery插件
1.引入jquery,并且在vue.config.js里配置 config.plugin('provide') .use(webpack.ProvidePlugin, [{ $: 'jquery', ...
- 【转载】【PAT】PAT甲级题型分类整理
最短路径 Emergency (25)-PAT甲级真题(Dijkstra算法) Public Bike Management (30)-PAT甲级真题(Dijkstra + DFS) Travel P ...
- 工作笔记 之 Python应用技术
python socket编程详细介绍 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,建立网络通信连接至少要一对端口号(socket). Socket本质是 ...
- PAT 1009 Product of Polynomials 模拟
This time, you are supposed to find A*B where A and B are two polynomials. Input Specification: Each ...
- HTML识别后台传输或者js变量中字符串里的 '\n' 并成功换行显示
HTML识别 string 里的 '\n' 并成功换行显示 设置标签的的css属性 white-space: pre-line; <div style='white-space: pre-lin ...
- Winform中在使用VS+svn进行协同开发时添加引用时的相对路径和绝对路径的问题
场景 使用Visual Studio 开发Winform程序,使用SVN进行项目版本管理. 在添加引用时,会出现在A电脑中添加了绝对路径的引用,在B电脑中就会出现找不到 并且将此引用标识为?的状态. ...
- cmdb项目-2
1.命令插件异常处理 + 日志采集 1)为了更清楚发送客户端收集信息的状态 ,优化返回api的数据 ,变为字典存储 {状态 错误信息 数据} ,因为每个插件的每种系统下都要这个返回值我们将他单独做成类 ...