D. Ball CF

D. Ball
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

N ladies attend the ball in the King's palace. Every lady can be described with three values: beauty, intellect and richness. King's Master of Ceremonies knows that ladies are very special creatures. If some lady understands that there is other lady at the ball which is more beautiful, smarter and more rich, she can jump out of the window. He knows values of all ladies and wants to find out how many probable self-murderers will be on the ball. Lets denote beauty of thei-th lady by Bi, her intellect byIi and her richness byRi. Theni-th lady is a probable self-murderer if there is somej-th lady that Bi < Bj, Ii < Ij, Ri < Rj. Find the number of probable self-murderers.

Input

The first line contains one integer N (1 ≤ N ≤ 500000). The second line containsN integer numbers Bi, separated by single spaces. The third and the fourth lines contain sequencesIi andRi in the same format. It is guaranteed that0 ≤ Bi, Ii, Ri ≤ 109.

Output

Output the answer to the problem.

Sample test(s)
Input
3
1 4 2
4 3 2
2 5 3
Output
1

http://codeforces.com/problemset/problem/12/D

//这三维 一维是插入顺序 一维是插入位置 一维是插入的值
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)

const int maxn=500050;
struct node{
    int b,i,r;
}p[maxn];
int num[maxn];
int tot;

int Bin(int x)
{
    int l=0,r=tot,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(num[mid]<x)
            l=mid+1;
        else if(num[mid]>x)
            r=mid-1;
        else
            return mid;
    }
    return -1;
}

int cmp(node x,node y)
{
    if(x.b!=y.b) return x.b<y.b;
    if(x.i!=y.i) return x.i<y.i;
    return x.r<y.r;
}

struct Seg{
    int l,r;
    int max;
}tree[maxn*3];

void build(int l,int r,int k)
{
    tree[k].l=l;
    tree[k].r=r;
    tree[k].max=-1;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(l,mid,LL(k));
    build(mid+1,r,RR(k));
}

int Max(int a,int b){
    if(a>b) return a;
    return b;
}

void update(int l,int k,int val)
{
    if(l==tree[k].l && l==tree[k].r)
    {
        tree[k].max=Max(tree[k].max,val);
        return ;
    }
    int mid=(tree[k].l+tree[k].r)>>1;
    if(l<=mid) update(l,LL(k),val);
    else update(l,RR(k),val);
    tree[k].max=Max(tree[LL(k)].max,tree[RR(k)].max);
}

int query(int l,int r,int k)
{
    if(l>r) return -1;
    if(l<=tree[k].l && tree[k].r<=r)
        return tree[k].max;
    int mid=(tree[k].l+tree[k].r)>>1;
    if(r<=mid) return query(l,r,LL(k));
    else if(l>mid) return query(l,r,RR(k));
    else    return Max(query(l,r,LL(k)),query(l,r,RR(k)));
}

int main()
{
    int n;
    int i,j;
    while(scanf("%d",&n)!=EOF)
    {
        tot=0;
        for(i=0;i<n;i++)
            scanf("%d",&p[i].b);
        for(i=0;i<n;i++)
        {
            scanf("%d",&p[i].i);
            num[tot++]=p[i].i;
        }
        for(i=0;i<n;i++)
            scanf("%d",&p[i].r);
        sort(num,num+tot);
        for(i=1,j=0;i<tot;i++)
            if(num[j]!=num[i])
                num[++j]=num[i];
        tot=j;
        for(i=0;i<n;i++)
            p[i].i=Bin(p[i].i);
        sort(p,p+n,cmp);
        int ans=0;
        build(0,tot,1);
    //  for(i=0;i<n;i++)
    //  {
    //      printf("%d %d %d\n",p[i].b,p[i].i,p[i].r);
    //  }
        for(i=n-1,j=n-1;i>=0;i--)
        {
            while(p[j].b!=p[i].b && j>=0)
            {
                update(p[j].i,1,p[j].r);
                j--;
            }
            if(p[i].r<query(p[i].i+1,tot,1))
            {
            //  printf("i==%d\n",i);
                ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 
(not mine)

//树状数组 其实就是二叉树的性质求 (x+1->tot  tot定值)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 500010;
int c[N];
int num[N];
int n;
struct node{
    int x,y,z;
}in[N];
inline int Max(int &a,int b){
    if(a<b) return b;
    return a;
}
void update(int x,int d){
    for(;x<N;x+=x&-x)   c[x]=Max(c[x],d);
}
int sum(int x){
    int ans=0;
    for(;x>0;x-=x&-x)   ans=Max(ans,c[x]);
    return ans;
}
void init(){
     sort(num+1,num+n+1);
     int tot=unique(num+1,num+n+1)-num-1;
     for(int i=1;i<=n;i++)
         in[i].x=tot-(lower_bound(num+1,num+1+tot,in[i].x)-num-1);
}
inline int cmp(node a,node b){
    return a.y>b.y;
}
int main()
{
    int i,j,k;
    scanf("%d",&n);
    for(i=1;i<=n;i++) {scanf("%d",&in[i].x);    num[i]=in[i].x;}
    for(i=1;i<=n;i++) scanf("%d",&in[i].y);
    for(i=1;i<=n;i++) scanf("%d",&in[i].z);
    init();
    memset(c,0,sizeof(c));
    sort(in+1,in+n+1,cmp);
    int ans=0;
    for(i=1;i<=n;i=j){
        for(j=i;j<=n&&in[j].y==in[i].y;j++){
            int z=sum(in[j].x-1);
            if(z>in[j].z) ans++;
        }
        for(;i<=j-1;i++)
            update(in[i].x,in[i].z);
    }
    printf("%d\n",ans);
    return 0;
}




<think>我们遇到了一个计算实数平方根时出现负数的问题。错误信息指出在计算变量`comp1.ball`时出现问题,该变量定义为 `sqrt(((R^2)-(x^2))-(y^2))`。这通常是因为表达式`((R^2)-(x^2))-(y^2)`在某些区域计算为负数,导致平方根无法计算。 ###原因分析:1.**定义域超限**:当点`(x,y)`超出球面投影的圆形区域(即 `x^2+y^2> R^2`)时,表达式 `(R^2- x^2- y^2)`为负。2.**几何范围过大**:如果几何模型的范围大于半径`R`,边界区域必然出现负数。 ###解决方案: ####方法1:限制定义域修改`comp1.ball`的定义,使用条件表达式避免负数开方: ```jsif (x^2+y^2< R^2, sqrt(R^2- x^2- y^2),0)``` 或使用平滑过渡(避免不连续): ```jssqrt(max(R^2 -x^2 -y^2,0)) ```####方法2:调整几何确保几何模型的尺寸不超过球面投影的有效范围(即直径不超过 `2*R`)。 ####方法3:检查单位确认`R`和坐标`x,y`的单位一致(例如都是米)。####方法4:使用解析函数若球面仅用于初始条件,可改用**解析函数**定义,并设置有效范围:1.创建解析函数 `ball_func`,表达式为 `sqrt(R^2-x^2 -y^2)`。 2.在定义域设置中指定作用域(如圆形区域)。 ###操作步骤(以方法1为例):1.**修改变量定义**在`组件>定义 >变量`中,找到`comp1.ball`,将其表达式改为:```sqrt(max(R^2- x^2- y^2,0))//推荐:自动将负值归零```或```(x^2+y^2 <R^2)*sqrt(R^2- x^2- y^2)//条件表达式``` 2. **重新检查模型**运行计算前,通过“更新解”或“重新初始化”测试表达式是否有效。 ###进阶建议: -**可视化验证**:在“结果”中创建表面图,绘制 `comp1.ball`观察其分布。- **参数化扫描**:测试不同 `R`值对初始形状的影响。--- §§相关问题§§1. COMSOL中如何为变量定义添加条件判断(如if语句)以避免数学错误?2.使用`max()`函数处理平方根定义域时,会对数值求解的稳定性产生什么影响?3.除了修改表达式,还有哪些方法可以确保几何模型尺寸与物理定义域匹配?4.在COMSOL中如何快速检测一个变量表达式是否在求解域内有效?5.对于复杂几何形状的初始位移场,如何避免类似的开方运算错误?</think>### 问题分析与解决方案 您在COMSOL中遇到的计算错误是由于表达式 `sqrt(((R^2)-(x^2))-(y^2))` 在部分区域出现负数导致的实数平方根计算错误。以下是具体原因和解决方案: #### 错误原因: 1. **定义域超限**:当 `(x^2 + y^2) > R^2` 时,表达式 `(R^2 - x^2 - y^2)` 为负值 2. **几何边界问题**:模型边界处的点超出球面有效区域 3. **单位不一致**:坐标单位与半径 `R` 单位不匹配(如 m 与 mm) #### 解决方案: 1. **添加条件限制**(推荐) 修改原表达式为: ```js if (x^2 + y^2 < R^2, sqrt(R^2 - x^2 - y^2), 0) ``` 或使用平滑过渡: ```js sqrt(max(R^2 - x^2 - y^2, 0)) ``` 2. **几何范围调整** - 在几何设置中限制计算域:创建半径为 `R` 的圆形域 - 使用布尔运算:`Geometry > Boolean Operations` 设置 `x^2 + y^2 ≤ R^2` 3. **坐标系修正** 若球心不在原点,修正表达式为: ```js sqrt(R^2 - (x-x0)^2 - (y-y0)^2) // (x0,y0)为球心坐标 ``` 4. **单位系统检查** 在 `Global Definitions > Units` 中确认: - 几何单位(如 mm) - 变量 `R` 的单位一致性 ### 操作步骤: 1. 打开变量定义:`Component > Definitions > Variables` 2. 找到 `comp1.ball` 并修改表达式 3. 添加条件语句后,点击"更新解"测试 4. 在结果中绘制 `comp1.ball` 验证分布 > **验证建议**: > 创建截面图,绘制表达式 `R^2 - x^2 - y^2`,确认所有区域值 ≥0 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值