A-平面
题目链接:https://www.nowcoder.com/acm/contest/180#question 
 假设有n条直线,增加第         条直线,最多与前面         条直线相交,因此         条直线最多相交出         个点,记点数为: 
条直线 个交点能够分成多少条线段呢? 条
记线段的个数为:
然后就阔以用 欧拉平面公式 计算区域数了:
D-XOR序列
原来这个就是线性基的经典操作题,还是第一次听说这个 
 大概的过程就跟求线性代数里的 行最简形 差不多 
 用样例来讲一讲大概的过程: 
 有5个数{1,2,3,4,5},化成二进制最大的数也只有3位,因此是构造一个         的矩阵 
 最开始是: 
 
然后加入       ,因为最高位在第         位,所以加在最后一行 
 
然后加入 ,最高位在第 位,所以加在第二行
然后加入 ,本来应该加在第二行的,但是第二行已经不是0了,所以用第二行把 中的第1位消掉,变成了 ,然后第3行也不是0,又用第三行把第0位消掉,就变成了 ,所以相当于 这个数对矩阵没有做贡献,为什么喃?因为 阔以用 和 线性组合表示出来。
再加入         矩阵变成: 
 
也加不进去了
然后矩阵就构造好了,怎么用喃? 
 假设要看能不能异或出来一个数,就从最高位开始枚举,如果那一位有1,就对应的行去异或,最后如果等于0,那就说明阔以异或出来。
#include"bits/stdc++.h"
using namespace std;
const int maxn=1e6+5;
const int MOD=1e9+7;
typedef long long LL;
int p[35];
int main()
{
    int N,Q;
    cin>>N;
    for(int i=1;i<=N;i++)
    {
        int t;
        cin>>t;
        for(int j=31;j>=0;j--)//从高位开始枚举这个数的每一位 
        {
            if(t&(1<<j))//假如第j位有1 
            {
                if(p[j]==0)//如果这一行还没有动过,就直接赋值 
                {
                    p[j]=t;
                    break;
                }
                else t^=p[j];//用第j行来消去开头的t的第j位的1 
            }
        }
    }
    cin>>Q;
    while(Q--)
    {
        int x,y;
        cin>>x>>y;
        x^=y;
        for(int j=31;j>=0;j--)if(x&(1<<j))x^=p[j];
        if(x==0)cout<<"YES\n";
        else cout<<"NO\n";
    }
}  B-烟花
就跟背包问题差不多,每次考虑这个物品取或者不取:
二维的:
表示前 个物品中取 个的概率
#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
#define C(n,m) (m>n?0:(long long)fac[(n)]*invf[(m)]%MOD*invf[(n)-(m)]%MOD)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
double dp[maxn][205];
double p[maxn];
double sum;
int main()
{
    cout.setf(ios::fixed);
    int N,K;
    while(cin>>N>>K)
    {
        memset(dp,0,sizeof dp);
        sum=0;
        cin>>p[1];
        sum+=p[1];
        dp[1][1]=p[1],dp[1][0]=1-p[1];
        for(int i=2;i<=N;i++)
        {
            cin>>p[i];
            sum+=p[i];
            for(int k=1;k<=i&&k<=K;k++)
            {
                dp[i][k]=p[i]*dp[i-1][k-1]+(1.0-p[i])*dp[i-1][k];
            }
        }
        cout<<setprecision(4)<<sum<<endl<<dp[N][K]<<endl;
    }
}  一维的:
#include"bits/stdc++.h"
#define out(x) cout<<#x<<"="<<x
#define C(n,m) (m>n?0:(long long)fac[(n)]*invf[(m)]%MOD*invf[(n)-(m)]%MOD)
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
double dp[205];
double sum,p;
int main()
{
    cout.setf(ios::fixed);
    int N,K;
    while(cin>>N>>K)
    {
        memset(dp,0,sizeof dp);
        sum=0;
        dp[0]=1;
        for(int i=1; i<=N; i++)
        {
            cin>>p;
            sum+=p;
            for(int k=K; k>=1; k--)
            {
                dp[k]=1.0*dp[k-1]*p+1.0*dp[k]*(1-p);
            }
            dp[0]=dp[0]*(1-p);//dp[0]代表的是前i个的物品取0个的概率,所以每次是要变的 
        }
        cout<<setprecision(4)<<sum<<endl<<dp[K]<<endl;
    }
}
京公网安备 11010502036488号